summaryrefslogtreecommitdiff
path: root/src/pkg/syscall/exec_unix.go
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-06-28 15:28:34 +0200
committerOndřej Surý <ondrej@sury.org>2011-06-28 15:28:34 +0200
commit8d00b02d82d86abe51773dc2c1751843bb538ae5 (patch)
tree6656d166a046fc751548e88f071fedbeb9355443 /src/pkg/syscall/exec_unix.go
parentc29cace1e8f3260389ea78fa4ef86d80cd5e5275 (diff)
downloadgolang-8d00b02d82d86abe51773dc2c1751843bb538ae5.tar.gz
Imported Upstream version 2011.06.23upstream-weekly/2011.06.23
Diffstat (limited to 'src/pkg/syscall/exec_unix.go')
-rw-r--r--src/pkg/syscall/exec_unix.go77
1 files changed, 44 insertions, 33 deletions
diff --git a/src/pkg/syscall/exec_unix.go b/src/pkg/syscall/exec_unix.go
index b6cb1baa2..4b3cfe47f 100644
--- a/src/pkg/syscall/exec_unix.go
+++ b/src/pkg/syscall/exec_unix.go
@@ -62,7 +62,7 @@ var ForkLock sync.RWMutex
// Convert array of string to array
// of NUL-terminated byte pointer.
-func StringArrayPtr(ss []string) []*byte {
+func StringSlicePtr(ss []string) []*byte {
bb := make([]*byte, len(ss)+1)
for i := 0; i < len(ss); i++ {
bb[i] = StringBytePtr(ss[i])
@@ -96,7 +96,7 @@ func SetNonblock(fd int, nonblocking bool) (errno int) {
// no rescheduling, no malloc calls, and no new stack segments.
// The calls to RawSyscall are okay because they are assembly
// functions that do not grow the stack.
-func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, pipe int) (pid int, err int) {
+func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, 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
@@ -131,7 +131,7 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
// Fork succeeded, now in child.
// Enable tracing if requested.
- if attr.Ptrace {
+ if sys.Ptrace {
_, _, err1 = RawSyscall(SYS_PTRACE, uintptr(PTRACE_TRACEME), 0, 0)
if err1 != 0 {
goto childerror
@@ -139,7 +139,7 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
}
// Session ID
- if attr.Setsid {
+ if sys.Setsid {
_, _, err1 = RawSyscall(SYS_SETSID, 0, 0, 0)
if err1 != 0 {
goto childerror
@@ -155,21 +155,21 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
}
// User and groups
- if attr.Credential != nil {
- ngroups := uintptr(len(attr.Credential.Groups))
+ if cred := sys.Credential; cred != nil {
+ ngroups := uintptr(len(cred.Groups))
groups := uintptr(0)
if ngroups > 0 {
- groups = uintptr(unsafe.Pointer(&attr.Credential.Groups[0]))
+ groups = uintptr(unsafe.Pointer(&cred.Groups[0]))
}
_, _, err1 = RawSyscall(SYS_SETGROUPS, ngroups, groups, 0)
if err1 != 0 {
goto childerror
}
- _, _, err1 = RawSyscall(SYS_SETGID, uintptr(attr.Credential.Gid), 0, 0)
+ _, _, err1 = RawSyscall(SYS_SETGID, uintptr(cred.Gid), 0, 0)
if err1 != 0 {
goto childerror
}
- _, _, err1 = RawSyscall(SYS_SETUID, uintptr(attr.Credential.Uid), 0, 0)
+ _, _, err1 = RawSyscall(SYS_SETUID, uintptr(cred.Uid), 0, 0)
if err1 != 0 {
goto childerror
}
@@ -249,7 +249,7 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
childerror:
// send error code on pipe
- RawSyscall(SYS_WRITE, uintptr(pipe), uintptr(unsafe.Pointer(&err1)), uintptr(unsafe.Sizeof(err1)))
+ RawSyscall(SYS_WRITE, uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
for {
RawSyscall(SYS_EXIT, 253, 0, 0)
}
@@ -267,16 +267,21 @@ type Credential struct {
}
type ProcAttr struct {
- Setsid bool // Create session.
- Ptrace bool // Enable tracing.
- Dir string // Current working directory.
- Env []string // Environment.
- Files []int // File descriptors.
+ Dir string // Current working directory.
+ Env []string // Environment.
+ Files []int // File descriptors.
+ Sys *SysProcAttr
+}
+
+type SysProcAttr struct {
Chroot string // Chroot.
Credential *Credential // Credential.
+ Ptrace bool // Enable tracing.
+ Setsid bool // Create session.
}
-var zeroAttributes ProcAttr
+var zeroProcAttr ProcAttr
+var zeroSysProcAttr SysProcAttr
func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err int) {
var p [2]int
@@ -285,7 +290,11 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err int) {
var wstatus WaitStatus
if attr == nil {
- attr = &zeroAttributes
+ attr = &zeroProcAttr
+ }
+ sys := attr.Sys
+ if sys == nil {
+ sys = &zeroSysProcAttr
}
p[0] = -1
@@ -293,16 +302,16 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err int) {
// Convert args to C form.
argv0p := StringBytePtr(argv0)
- argvp := StringArrayPtr(argv)
- envvp := StringArrayPtr(attr.Env)
+ argvp := StringSlicePtr(argv)
+ envvp := StringSlicePtr(attr.Env)
if OS == "freebsd" && len(argv[0]) > len(argv0) {
argvp[0] = argv0p
}
var chroot *byte
- if attr.Chroot != "" {
- chroot = StringBytePtr(attr.Chroot)
+ if sys.Chroot != "" {
+ chroot = StringBytePtr(sys.Chroot)
}
var dir *byte
if attr.Dir != "" {
@@ -326,24 +335,18 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err int) {
}
// Kick off child.
- pid, err = forkAndExecInChild(argv0p, argvp, envvp, chroot, dir, attr, p[1])
+ pid, err = forkAndExecInChild(argv0p, argvp, envvp, chroot, dir, attr, sys, p[1])
if err != 0 {
- error:
- if p[0] >= 0 {
- Close(p[0])
- Close(p[1])
- }
- ForkLock.Unlock()
- return 0, err
+ goto error
}
ForkLock.Unlock()
// Read child error status from pipe.
Close(p[1])
- n, err = read(p[0], (*byte)(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
+ n, err = read(p[0], (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1)))
Close(p[0])
if err != 0 || n != 0 {
- if n == unsafe.Sizeof(err1) {
+ if n == int(unsafe.Sizeof(err1)) {
err = int(err1)
}
if err == 0 {
@@ -361,6 +364,14 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err int) {
// Read got EOF, so pipe closed on exec, so exec succeeded.
return pid, 0
+
+error:
+ if p[0] >= 0 {
+ Close(p[0])
+ Close(p[1])
+ }
+ ForkLock.Unlock()
+ return 0, err
}
// Combination of fork and exec, careful to be thread safe.
@@ -378,7 +389,7 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid, handle int,
func Exec(argv0 string, argv []string, envv []string) (err int) {
_, _, err1 := RawSyscall(SYS_EXECVE,
uintptr(unsafe.Pointer(StringBytePtr(argv0))),
- uintptr(unsafe.Pointer(&StringArrayPtr(argv)[0])),
- uintptr(unsafe.Pointer(&StringArrayPtr(envv)[0])))
+ uintptr(unsafe.Pointer(&StringSlicePtr(argv)[0])),
+ uintptr(unsafe.Pointer(&StringSlicePtr(envv)[0])))
return int(err1)
}