diff options
author | Russ Cox <rsc@golang.org> | 2009-02-15 19:35:52 -0800 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2009-02-15 19:35:52 -0800 |
commit | 6c76acf88cb2c97bf60c34caa01e868f61bad436 (patch) | |
tree | 9600ec63eb31a171bc1f911505eae0806b9d33d5 /src/lib/os/exec.go | |
parent | 491b1c363470e285bb91b69c32e6a023dcc66643 (diff) | |
download | golang-6c76acf88cb2c97bf60c34caa01e868f61bad436.tar.gz |
add os.ForkExec, os.Exec, os.Wait, exec.OpenCmd.
as thread-safe as possible, given the surrounding system.
add stub RWLock implementation.
R=r
DELTA=852 (834 added, 6 deleted, 12 changed)
OCL=25046
CL=25053
Diffstat (limited to 'src/lib/os/exec.go')
-rw-r--r-- | src/lib/os/exec.go | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/lib/os/exec.go b/src/lib/os/exec.go new file mode 100644 index 000000000..0ce51773c --- /dev/null +++ b/src/lib/os/exec.go @@ -0,0 +1,70 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package os + +import ( + "os"; + "syscall"; +) + +func ForkExec(argv0 string, argv []string, envv []string, fd []*FD) + (pid int, err *Error) +{ + // Create array of integer (system) fds. + intfd := make([]int64, len(fd)); + for i, f := range(fd) { + if f == nil { + intfd[i] = -1; + } else { + intfd[i] = f.Fd(); + } + } + + p, e := syscall.ForkExec(argv0, argv, envv, intfd); + return int(p), ErrnoToError(e); +} + +func Exec(argv0 string, argv []string, envv []string) *Error { + e := syscall.Exec(argv0, argv, envv); + return ErrnoToError(e); +} + +// TODO(rsc): Should os implement its own syscall.WaitStatus +// wrapper with the methods, or is exposing the underlying one enough? +// +// TODO(rsc): Certainly need to have os.Rusage struct, +// since syscall one might have different field types across +// different OS. + +type Waitmsg struct { + Pid int; + syscall.WaitStatus; + Rusage *syscall.Rusage; +} + +const ( + WNOHANG = syscall.WNOHANG; + WSTOPPED = syscall.WSTOPPED; + WRUSAGE = 1<<60; +) + +func Wait(pid int, options uint64) (w *Waitmsg, err *Error) { + var status syscall.WaitStatus; + var rusage *syscall.Rusage; + if options & WRUSAGE != 0 { + rusage = new(syscall.Rusage); + options ^= WRUSAGE; + } + pid1, e := syscall.Wait4(int64(pid), &status, int64(options), rusage); + if e != 0 { + return nil, ErrnoToError(e); + } + w = new(Waitmsg); + w.Pid = pid; + w.WaitStatus = status; + w.Rusage = rusage; + return w, nil; +} + |