]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: fix fork-exec/wait inconsistencies for Plan 9
authorAkshat Kumar <seed@mail.nanosouffle.net>
Wed, 23 Jan 2013 03:42:44 +0000 (22:42 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 23 Jan 2013 03:42:44 +0000 (22:42 -0500)
Fixes the fork-exec/wait race condition for ForkExec
as well, by making it use startProcess. This makes the
comment for StartProcess consistent as well.

Further, the passing of Waitmsg data in startProcess
and WaitProcess is protected against possible forks
from outside of ForkExec and StartProcess, which might
cause interference with the Await call.

R=rsc, rminnich, npe, ality
CC=golang-dev
https://golang.org/cl/7128059

src/pkg/syscall/exec_plan9.go

index ae0cd0d4b5e74db4f2adb997c30f0b9da72b8bef..ebd57f3e3a7c254428375caff6951247bb88e576 100644 (file)
@@ -495,11 +495,6 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
        return pid, nil
 }
 
-// Combination of fork and exec, careful to be thread safe.
-func ForkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
-       return forkExec(argv0, argv, attr)
-}
-
 type waitErr struct {
        Waitmsg
        err error
@@ -551,7 +546,9 @@ func startProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, err err
                forkc <- ret
 
                var w waitErr
-               w.err = Await(&w.Waitmsg)
+               for w.err == nil && w.Pid != ret.pid {
+                       w.err = Await(&w.Waitmsg)
+               }
                waitc <- &w
                close(waitc)
        }()
@@ -559,6 +556,11 @@ func startProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, err err
        return ret.pid, ret.err
 }
 
+// Combination of fork and exec, careful to be thread safe.
+func ForkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
+       return startProcess(argv0, argv, attr)
+}
+
 // StartProcess wraps ForkExec for package os.
 func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
        pid, err = startProcess(argv0, argv, attr)
@@ -612,8 +614,8 @@ func Exec(argv0 string, argv []string, envv []string) (err error) {
 // WaitProcess waits until the pid of a
 // running process is found in the queue of
 // wait messages. It is used in conjunction
-// with StartProcess to wait for a running
-// process to exit.
+// with ForkExec/StartProcess to wait for a
+// running process to exit.
 func WaitProcess(pid int, w *Waitmsg) (err error) {
        procs.Lock()
        ch := procs.waits[pid]