diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-03-24 23:46:17 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-03-24 23:46:17 +0000 |
commit | 8039ca76a5705ae5052b20cee64110c32545c4fc (patch) | |
tree | 9319bca77115a32f6a0b5e8bcd651465b14c76da /libgo/syscalls | |
parent | 7114321ee4f521ea9fbdd08a4c23b361181f3658 (diff) | |
download | gcc-8039ca76a5705ae5052b20cee64110c32545c4fc.zip gcc-8039ca76a5705ae5052b20cee64110c32545c4fc.tar.gz gcc-8039ca76a5705ae5052b20cee64110c32545c4fc.tar.bz2 |
Update to current version of Go library.
From-SVN: r171427
Diffstat (limited to 'libgo/syscalls')
-rw-r--r-- | libgo/syscalls/exec.go | 67 |
1 files changed, 46 insertions, 21 deletions
diff --git a/libgo/syscalls/exec.go b/libgo/syscalls/exec.go index 7a9ee28..64b40bd 100644 --- a/libgo/syscalls/exec.go +++ b/libgo/syscalls/exec.go @@ -12,6 +12,7 @@ import "unsafe" func libc_fcntl(fd int, cmd int, arg int) int __asm__ ("fcntl") func libc_fork() Pid_t __asm__ ("fork") +func libc_setsid() Pid_t __asm__ ("setsid") func libc_chdir(name *byte) int __asm__ ("chdir") func libc_dup2(int, int) int __asm__ ("dup2") func libc_execve(*byte, **byte, **byte) int __asm__ ("execve") @@ -24,13 +25,16 @@ func libc_wait4(Pid_t, *int, int, *Rusage) Pid_t __asm__ ("wait4") // In the child, this function must not acquire any locks, because // they might have been locked at the time of the fork. This means // no rescheduling, no malloc calls, and no new stack segments. -func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, traceme bool, dir *byte, fd []int, pipe int) (pid int, err int) { +func forkAndExecInChild(argv0 *byte, argv, envv []*byte, dir *byte, attr *ProcAttr, pipe int) (pid int, err int) { // Declare all variables at top in case any // declarations require heap allocation (e.g., err1). var r1, r2, err1 uintptr var nextfd int var i int + // guard against side effects of shuffling fds below. + fd := append([]int(nil), attr.Files...) + darwin := OS == "darwin" // About to call fork. @@ -48,16 +52,22 @@ func forkAndExecInChild(argv0 *byte, argv []*byte, envv []*byte, traceme bool, d // Fork succeeded, now in child. // Enable tracing if requested. - if traceme { + if attr.Ptrace { if libc_ptrace(_PTRACE_TRACEME, 0, 0, nil) < 0 { goto childerror } } + // Session ID + if attr.Setsid { + if libc_setsid() == Pid_t(-1) { + goto childerror + } + } + // Chdir if dir != nil { - r := libc_chdir(dir) - if r < 0 { + if libc_chdir(dir) < 0 { goto childerror } } @@ -138,22 +148,42 @@ childerror: panic("unreached") } -func forkExec(argv0 string, argv []string, envv []string, traceme bool, dir string, fd []int) (pid int, err int) { + +type ProcAttr struct { + Setsid bool // Create session. + Ptrace bool // Enable tracing. + Dir string // Current working directory. + Env []string // Environment. + Files []int // File descriptors. +} + +var zeroAttributes ProcAttr + +func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err int) { var p [2]int var r1 int var err1 uintptr var wstatus WaitStatus + if attr == nil { + attr = &zeroAttributes + } + p[0] = -1 p[1] = -1 // Convert args to C form. argv0p := StringBytePtr(argv0) argvp := StringArrayPtr(argv) - envvp := StringArrayPtr(envv) - var dirp *byte - if len(dir) > 0 { - dirp = StringBytePtr(dir) + envvp := StringArrayPtr(attr.Env) + + if OS == "freebsd" && len(argv[0]) > len(argv0) { + argvp[0] = argv0p + } + + var dir *byte + if attr.Dir != "" { + dir = StringBytePtr(attr.Dir) } // Acquire the fork lock so that no other threads @@ -173,7 +203,7 @@ func forkExec(argv0 string, argv []string, envv []string, traceme bool, dir stri } // Kick off child. - pid, err = forkAndExecInChild(argv0p, argvp, envvp, traceme, dirp, fd, p[1]) + pid, err = forkAndExecInChild(argv0p, argvp, envvp, dir, attr, p[1]) if err != 0 { error: if p[0] >= 0 { @@ -216,13 +246,14 @@ func forkExec(argv0 string, argv []string, envv []string, traceme bool, dir stri } // Combination of fork and exec, careful to be thread safe. -func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []int) (pid int, err int) { - return forkExec(argv0, argv, envv, false, dir, fd) +func ForkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err int) { + return forkExec(argv0, argv, attr) } -// PtraceForkExec is like ForkExec, but starts the child in a traced state. -func PtraceForkExec(argv0 string, argv []string, envv []string, dir string, fd []int) (pid int, err int) { - return forkExec(argv0, argv, envv, true, dir, fd) +// StartProcess wraps ForkExec for package os. +func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid, handle int, err int) { + pid, err = forkExec(argv0, argv, attr) + return pid, 0, err } // Ordinary exec. @@ -233,12 +264,6 @@ func Exec(argv0 string, argv []string, envv []string) (err int) { return GetErrno() } -// StartProcess wraps ForkExec for package os. -func StartProcess(argv0 string, argv []string, envv []string, dir string, fd []int) (pid, handle int, err int) { - pid, err = forkExec(argv0, argv, envv, false, dir, fd) - return pid, 0, err -} - func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, errno int) { var status int r := libc_wait4(Pid_t(pid), &status, options, rusage) |