delve/vendor/github.com/cosiner/argv/cmd.go
Yasushi Saito c5c41f6352 command/terminal: allow restart to change process args (#1060)
* command/terminal: allow restart to change process args

Add -args flag to "restart" command. For example, "restart -args a b c" will
pass args a b c to the new process.

Add "-c" flag to pass the checkpoint name. This is needed to disambiguate the
checkpoint name and arglist.

Reverted unnecessary changes.

* Applied reviewer comments.

Vendored argv.

Change the syntax of restart. When the target is is in recording mode, it always
interprets the args as a checkpoint. Otherwise, it interprets the args as
commandline args. The flag "-args" is still there, to handle the case in which
the user wants to pass an empty args on restart.

* Add restartargs.go.

Change "restart -args" to "restart -noargs" to clarify that this flag is used to
start a process with an empty arg.
2018-01-18 14:16:11 -08:00

80 lines
1.4 KiB
Go

package argv
import (
"bytes"
"errors"
"io"
"os/exec"
"strings"
)
// Run execute cmdline string and return the output
func Run(cmdline []rune, env map[string]string) ([]rune, error) {
args, err := Argv(cmdline, env, Run)
if err != nil {
return nil, err
}
cmds, err := Cmds(args)
if err != nil {
return nil, err
}
output := bytes.NewBuffer(make([]byte, 0, 1024))
err = Pipe(nil, output, cmds...)
str := output.String()
str = strings.TrimSpace(str)
return []rune(str), err
}
// Cmds generate exec.Cmd for each command.
func Cmds(args [][]string) ([]*exec.Cmd, error) {
var cmds []*exec.Cmd
for _, argv := range args {
if len(argv) == 0 {
return nil, errors.New("invalid cmd")
}
cmds = append(cmds, exec.Command(argv[0], argv[1:]...))
}
return cmds, nil
}
// Pipe pipe previous command's stdout to next command's stdin, if in or
// out is nil, it will be ignored.
func Pipe(in io.Reader, out io.Writer, cmds ...*exec.Cmd) error {
l := len(cmds)
if l == 0 {
return nil
}
var err error
for i := 1; i < l; i++ {
cmds[i].Stdin, err = cmds[i-1].StdoutPipe()
if err != nil {
break
}
}
if err != nil {
return err
}
if in != nil {
cmds[0].Stdin = in
}
if out != nil {
cmds[l-1].Stdout = out
}
for i := range cmds {
err = cmds[i].Start()
if err != nil {
return err
}
}
for i := range cmds {
err = cmds[i].Wait()
if err != nil {
return err
}
}
return nil
}