summaryrefslogtreecommitdiff
path: root/libgo/go/os
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2011-03-24 23:46:17 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2011-03-24 23:46:17 +0000
commitf97228863f84f4d7d87959ea40df40130f2ec912 (patch)
tree9319bca77115a32f6a0b5e8bcd651465b14c76da /libgo/go/os
parentd304b9e1af728d54ec16155c3d2116dc398c33c6 (diff)
downloadgcc-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.go43
-rw-r--r--libgo/go/os/inotify/inotify_linux_test.go16
-rw-r--r--libgo/go/os/os_test.go47
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)
}