aboutsummaryrefslogtreecommitdiff
path: root/libgo/syscalls
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-03-24 23:46:17 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-03-24 23:46:17 +0000
commit8039ca76a5705ae5052b20cee64110c32545c4fc (patch)
tree9319bca77115a32f6a0b5e8bcd651465b14c76da /libgo/syscalls
parent7114321ee4f521ea9fbdd08a4c23b361181f3658 (diff)
downloadgcc-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.go67
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)