diff options
| author | Ondřej Surý <ondrej@sury.org> | 2011-04-26 09:55:32 +0200 |
|---|---|---|
| committer | Ondřej Surý <ondrej@sury.org> | 2011-04-26 09:55:32 +0200 |
| commit | 7b15ed9ef455b6b66c6b376898a88aef5d6a9970 (patch) | |
| tree | 3ef530baa80cdf29436ba981f5783be6b4d2202b /src/pkg/exec | |
| parent | 50104cc32a498f7517a51c8dc93106c51c7a54b4 (diff) | |
| download | golang-7b15ed9ef455b6b66c6b376898a88aef5d6a9970.tar.gz | |
Imported Upstream version 2011.04.13upstream/2011.04.13
Diffstat (limited to 'src/pkg/exec')
| -rw-r--r-- | src/pkg/exec/exec.go | 16 | ||||
| -rw-r--r-- | src/pkg/exec/exec_test.go | 52 |
2 files changed, 63 insertions, 5 deletions
diff --git a/src/pkg/exec/exec.go b/src/pkg/exec/exec.go index 80f6f3c7d..5398eb8e0 100644 --- a/src/pkg/exec/exec.go +++ b/src/pkg/exec/exec.go @@ -2,9 +2,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// The exec package runs external commands. +// The exec package runs external commands. It wraps os.StartProcess +// to make it easier to remap stdin and stdout, connect I/O with pipes, +// and do other adjustments. package exec +// BUG(r): This package should be made even easier to use or merged into os. + import ( "os" "strconv" @@ -49,7 +53,7 @@ func modeToFiles(mode, fd int) (*os.File, *os.File, os.Error) { if fd == 0 { rw = os.O_RDONLY } - f, err := os.Open(os.DevNull, rw, 0) + f, err := os.OpenFile(os.DevNull, rw, 0) return f, nil, err case PassThrough: switch fd { @@ -75,17 +79,19 @@ func modeToFiles(mode, fd int) (*os.File, *os.File, os.Error) { // Run starts the named binary running with // arguments argv and environment envv. +// If the dir argument is not empty, the child changes +// into the directory before executing the binary. // It returns a pointer to a new Cmd representing // the command or an error. // -// The parameters stdin, stdout, and stderr +// The arguments stdin, stdout, and stderr // specify how to handle standard input, output, and error. // The choices are DevNull (connect to /dev/null), // PassThrough (connect to the current process's standard stream), // Pipe (connect to an operating system pipe), and // MergeWithStdout (only for standard error; use the same // file descriptor as was used for standard output). -// If a parameter is Pipe, then the corresponding field (Stdin, Stdout, Stderr) +// If an argument is Pipe, then the corresponding field (Stdin, Stdout, Stderr) // of the returned Cmd is the other end of the pipe. // Otherwise the field in Cmd is nil. func Run(name string, argv, envv []string, dir string, stdin, stdout, stderr int) (c *Cmd, err os.Error) { @@ -105,7 +111,7 @@ func Run(name string, argv, envv []string, dir string, stdin, stdout, stderr int } // Run command. - c.Process, err = os.StartProcess(name, argv, envv, dir, fd[0:]) + c.Process, err = os.StartProcess(name, argv, &os.ProcAttr{Dir: dir, Files: fd[:], Env: envv}) if err != nil { goto Error } diff --git a/src/pkg/exec/exec_test.go b/src/pkg/exec/exec_test.go index 3a3d3b1a5..5e37b99ee 100644 --- a/src/pkg/exec/exec_test.go +++ b/src/pkg/exec/exec_test.go @@ -118,3 +118,55 @@ func TestAddEnvVar(t *testing.T) { t.Fatal("close:", err) } } + +var tryargs = []string{ + `2`, + `2 `, + "2 \t", + `2" "`, + `2 ab `, + `2 "ab" `, + `2 \ `, + `2 \\ `, + `2 \" `, + `2 \`, + `2\`, + `2"`, + `2\"`, + `2 "`, + `2 \"`, + ``, + `2 ^ `, + `2 \^`, +} + +func TestArgs(t *testing.T) { + for _, a := range tryargs { + argv := []string{ + "awk", + `BEGIN{printf("%s|%s|%s",ARGV[1],ARGV[2],ARGV[3])}`, + "/dev/null", + a, + "EOF", + } + exe, err := LookPath(argv[0]) + if err != nil { + t.Fatal("run:", err) + } + cmd, err := Run(exe, argv, nil, "", DevNull, Pipe, DevNull) + if err != nil { + t.Fatal("run:", err) + } + buf, err := ioutil.ReadAll(cmd.Stdout) + if err != nil { + t.Fatal("read:", err) + } + expect := "/dev/null|" + a + "|EOF" + if string(buf) != expect { + t.Errorf("read: got %q expect %q", buf, expect) + } + if err = cmd.Close(); err != nil { + t.Fatal("close:", err) + } + } +} |
