diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-24 23:46:17 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-24 23:46:17 +0000 |
commit | f97228863f84f4d7d87959ea40df40130f2ec912 (patch) | |
tree | 9319bca77115a32f6a0b5e8bcd651465b14c76da /libgo/go/os | |
parent | d304b9e1af728d54ec16155c3d2116dc398c33c6 (diff) | |
download | gcc-f97228863f84f4d7d87959ea40df40130f2ec912.tar.gz |
Update to current version of Go library.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171427 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go/os')
-rw-r--r-- | libgo/go/os/exec.go | 43 | ||||
-rw-r--r-- | libgo/go/os/inotify/inotify_linux_test.go | 16 | ||||
-rw-r--r-- | libgo/go/os/os_test.go | 47 |
3 files changed, 67 insertions, 39 deletions
diff --git a/libgo/go/os/exec.go b/libgo/go/os/exec.go index dbdfacc5857..9d80ccfbed4 100644 --- a/libgo/go/os/exec.go +++ b/libgo/go/os/exec.go @@ -21,27 +21,46 @@ func newProcess(pid, handle int) *Process { return p } -// StartProcess starts a new process with the program, arguments, -// and environment specified by name, argv, and envv. The fd array specifies the -// file descriptors to be set up in the new process: fd[0] will be Unix file -// descriptor 0 (standard input), fd[1] descriptor 1, and so on. A nil entry -// will cause the child to have no open file descriptor with that index. -// If dir is not empty, the child chdirs into the directory before execing the program. -func StartProcess(name string, argv []string, envv []string, dir string, fd []*File) (p *Process, err Error) { - if envv == nil { - envv = Environ() +// ProcAttr holds the attributes that will be applied to a new process +// started by StartProcess. +type ProcAttr struct { + // If Dir is non-empty, the child changes into the directory before + // creating the process. + Dir string + // If Env is non-nil, it gives the environment variables for the + // new process in the form returned by Environ. + // If it is nil, the result of Environ will be used. + Env []string + // Files specifies the open files inherited by the new process. The + // first three entries correspond to standard input, standard output, and + // standard error. An implementation may support additional entries, + // depending on the underlying operating system. A nil entry corresponds + // to that file being closed when the process starts. + Files []*File +} + +// StartProcess starts a new process with the program, arguments and attributes +// specified by name, argv and attr. +func StartProcess(name string, argv []string, attr *ProcAttr) (p *Process, err Error) { + sysattr := &syscall.ProcAttr{ + Dir: attr.Dir, + Env: attr.Env, + } + if sysattr.Env == nil { + sysattr.Env = Environ() } // Create array of integer (system) fds. - intfd := make([]int, len(fd)) - for i, f := range fd { + intfd := make([]int, len(attr.Files)) + for i, f := range attr.Files { if f == nil { intfd[i] = -1 } else { intfd[i] = f.Fd() } } + sysattr.Files = intfd - pid, h, e := syscall.StartProcess(name, argv, envv, dir, intfd) + pid, h, e := syscall.StartProcess(name, argv, sysattr) if e != 0 { return nil, &PathError{"fork/exec", name, Errno(e)} } diff --git a/libgo/go/os/inotify/inotify_linux_test.go b/libgo/go/os/inotify/inotify_linux_test.go index 332edcb644d..79c3bfa36e4 100644 --- a/libgo/go/os/inotify/inotify_linux_test.go +++ b/libgo/go/os/inotify/inotify_linux_test.go @@ -35,6 +35,7 @@ func TestInotifyEvents(t *testing.T) { // Receive events on the event channel on a separate goroutine eventstream := watcher.Event var eventsReceived = 0 + done := make(chan bool) go func() { for event := range eventstream { // Only count relevant events @@ -45,6 +46,7 @@ func TestInotifyEvents(t *testing.T) { t.Logf("unexpected event received: %s", event) } } + done <- true }() // Create a file @@ -64,16 +66,12 @@ func TestInotifyEvents(t *testing.T) { t.Log("calling Close()") watcher.Close() t.Log("waiting for the event channel to become closed...") - var i = 0 - for !closed(eventstream) { - if i >= 20 { - t.Fatal("event stream was not closed after 1 second, as expected") - } - t.Log("waiting for 50 ms...") - time.Sleep(50e6) // 50 ms - i++ + select { + case <-done: + t.Log("event channel closed") + case <-time.After(1e9): + t.Fatal("event stream was not closed after 1 second") } - t.Log("event channel closed") } diff --git a/libgo/go/os/os_test.go b/libgo/go/os/os_test.go index be5f4824e4f..bb1b8e31893 100644 --- a/libgo/go/os/os_test.go +++ b/libgo/go/os/os_test.go @@ -10,6 +10,7 @@ import ( "io" "io/ioutil" . "os" + "path/filepath" "strings" "syscall" "testing" @@ -405,25 +406,13 @@ func TestRename(t *testing.T) { } } -func TestForkExec(t *testing.T) { - var cmd, adir, expect string - var args []string +func exec(t *testing.T, dir, cmd string, args []string, expect string) { r, w, err := Pipe() if err != nil { t.Fatalf("Pipe: %v", err) } - if syscall.OS == "windows" { - cmd = Getenv("COMSPEC") - args = []string{Getenv("COMSPEC"), "/c cd"} - adir = Getenv("SystemRoot") - expect = Getenv("SystemRoot") + "\r\n" - } else { - cmd = "/bin/pwd" - args = []string{"pwd"} - adir = "/" - expect = "/\n" - } - p, err := StartProcess(cmd, args, nil, adir, []*File{nil, w, Stderr}) + attr := &ProcAttr{Dir: dir, Files: []*File{nil, w, Stderr}} + p, err := StartProcess(cmd, args, attr) if err != nil { t.Fatalf("StartProcess: %v", err) } @@ -434,12 +423,34 @@ func TestForkExec(t *testing.T) { io.Copy(&b, r) output := b.String() if output != expect { - args[0] = cmd - t.Errorf("exec %q returned %q wanted %q", strings.Join(args, " "), output, expect) + t.Errorf("exec %q returned %q wanted %q", + strings.Join(append([]string{cmd}, args...), " "), output, expect) } p.Wait(0) } +func TestStartProcess(t *testing.T) { + var dir, cmd, le string + var args []string + if syscall.OS == "windows" { + le = "\r\n" + cmd = Getenv("COMSPEC") + dir = Getenv("SystemRoot") + args = []string{"/c", "cd"} + } else { + le = "\n" + cmd = "/bin/pwd" + dir = "/" + args = []string{} + } + cmddir, cmdbase := filepath.Split(cmd) + args = append([]string{cmdbase}, args...) + // Test absolute executable path. + exec(t, dir, cmd, args, dir+le) + // Test relative executable path. + exec(t, cmddir, cmdbase, args, filepath.Clean(cmddir)+le) +} + func checkMode(t *testing.T, path string, mode uint32) { dir, err := Stat(path) if err != nil { @@ -747,7 +758,7 @@ func run(t *testing.T, cmd []string) string { if err != nil { t.Fatal(err) } - p, err := StartProcess("/bin/hostname", []string{"hostname"}, nil, "/", []*File{nil, w, Stderr}) + p, err := StartProcess("/bin/hostname", []string{"hostname"}, &ProcAttr{Files: []*File{nil, w, Stderr}}) if err != nil { t.Fatal(err) } |