aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/os/exec_posix.go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-04-07 17:09:10 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-04-07 17:09:10 +0000
commit405ca10418216fc078ecb29ff13a39c911e8d806 (patch)
tree39c2c0da7b6c220dd344f134fae07fba0d0266b2 /libgo/go/os/exec_posix.go
parenta751005d50fa7347131660e562c5fd9ce3dff75d (diff)
downloadgcc-405ca10418216fc078ecb29ff13a39c911e8d806.zip
gcc-405ca10418216fc078ecb29ff13a39c911e8d806.tar.gz
gcc-405ca10418216fc078ecb29ff13a39c911e8d806.tar.bz2
libgo: Update to current Go library.
From-SVN: r172106
Diffstat (limited to 'libgo/go/os/exec_posix.go')
-rw-r--r--libgo/go/os/exec_posix.go127
1 files changed, 127 insertions, 0 deletions
diff --git a/libgo/go/os/exec_posix.go b/libgo/go/os/exec_posix.go
new file mode 100644
index 0000000..9102dc0
--- /dev/null
+++ b/libgo/go/os/exec_posix.go
@@ -0,0 +1,127 @@
+// 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 "syscall"
+
+// StartProcess starts a new process with the program, arguments and attributes
+// specified by name, argv and attr.
+func StartProcess(name string, argv []string, attr *ProcAttr) (p *Process, err Error) {
+ sysattr := &syscall.ProcAttr{
+ Dir: attr.Dir,
+ Env: attr.Env,
+ }
+ if sysattr.Env == nil {
+ sysattr.Env = Environ()
+ }
+ // Create array of integer (system) fds.
+ intfd := make([]int, len(attr.Files))
+ for i, f := range attr.Files {
+ if f == nil {
+ intfd[i] = -1
+ } else {
+ intfd[i] = f.Fd()
+ }
+ }
+ sysattr.Files = intfd
+
+ pid, h, e := syscall.StartProcess(name, argv, sysattr)
+ if iserror(e) {
+ return nil, &PathError{"fork/exec", name, Errno(e)}
+ }
+ return newProcess(pid, h), nil
+}
+
+// Exec replaces the current process with an execution of the
+// named binary, with arguments argv and environment envv.
+// If successful, Exec never returns. If it fails, it returns an Error.
+// StartProcess is almost always a better way to execute a program.
+func Exec(name string, argv []string, envv []string) Error {
+ if envv == nil {
+ envv = Environ()
+ }
+ e := syscall.Exec(name, argv, envv)
+ if iserror(e) {
+ return &PathError{"exec", name, Errno(e)}
+ }
+ return nil
+}
+
+// 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 Rusage struct,
+// since syscall one might have different field types across
+// different OS.
+
+// Waitmsg stores the information about an exited process as reported by Wait.
+type Waitmsg struct {
+ Pid int // The process's id.
+ syscall.WaitStatus // System-dependent status info.
+ Rusage *syscall.Rusage // System-dependent resource usage info.
+}
+
+// Wait waits for process pid to exit or stop, and then returns a
+// Waitmsg describing its status and an Error, if any. The options
+// (WNOHANG etc.) affect the behavior of the Wait call.
+// Wait is equivalent to calling FindProcess and then Wait
+// and Release on the result.
+func Wait(pid int, options int) (w *Waitmsg, err Error) {
+ p, e := FindProcess(pid)
+ if e != nil {
+ return nil, e
+ }
+ defer p.Release()
+ return p.Wait(options)
+}
+
+// Convert i to decimal string.
+func itod(i int) string {
+ if i == 0 {
+ return "0"
+ }
+
+ u := uint64(i)
+ if i < 0 {
+ u = -u
+ }
+
+ // Assemble decimal in reverse order.
+ var b [32]byte
+ bp := len(b)
+ for ; u > 0; u /= 10 {
+ bp--
+ b[bp] = byte(u%10) + '0'
+ }
+
+ if i < 0 {
+ bp--
+ b[bp] = '-'
+ }
+
+ return string(b[bp:])
+}
+
+func (w Waitmsg) String() string {
+ // TODO(austin) Use signal names when possible?
+ res := ""
+ switch {
+ case w.Exited():
+ res = "exit status " + itod(w.ExitStatus())
+ case w.Signaled():
+ res = "signal " + itod(w.Signal())
+ case w.Stopped():
+ res = "stop signal " + itod(w.StopSignal())
+ if w.StopSignal() == syscall.SIGTRAP && w.TrapCause() != 0 {
+ res += " (trap " + itod(w.TrapCause()) + ")"
+ }
+ case w.Continued():
+ res = "continued"
+ }
+ if w.CoreDump() {
+ res += " (core dumped)"
+ }
+ return res
+}