1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
12 // Process stores the information about a process created by StartProcess.
18 func newProcess(pid, handle int) *Process {
19 p := &Process{pid, handle}
20 runtime.SetFinalizer(p, (*Process).Release)
24 // ProcAttr holds the attributes that will be applied to a new process
25 // started by StartProcess.
26 type ProcAttr struct {
27 // If Dir is non-empty, the child changes into the directory before
28 // creating the process.
30 // If Env is non-nil, it gives the environment variables for the
31 // new process in the form returned by Environ.
32 // If it is nil, the result of Environ will be used.
34 // Files specifies the open files inherited by the new process. The
35 // first three entries correspond to standard input, standard output, and
36 // standard error. An implementation may support additional entries,
37 // depending on the underlying operating system. A nil entry corresponds
38 // to that file being closed when the process starts.
42 // StartProcess starts a new process with the program, arguments and attributes
43 // specified by name, argv and attr.
44 func StartProcess(name string, argv []string, attr *ProcAttr) (p *Process, err Error) {
45 sysattr := &syscall.ProcAttr{
49 if sysattr.Env == nil {
50 sysattr.Env = Environ()
52 // Create array of integer (system) fds.
53 intfd := make([]int, len(attr.Files))
54 for i, f := range attr.Files {
63 pid, h, e := syscall.StartProcess(name, argv, sysattr)
65 return nil, &PathError{"fork/exec", name, Errno(e)}
67 return newProcess(pid, h), nil
70 // Exec replaces the current process with an execution of the
71 // named binary, with arguments argv and environment envv.
72 // If successful, Exec never returns. If it fails, it returns an Error.
73 // StartProcess is almost always a better way to execute a program.
74 func Exec(name string, argv []string, envv []string) Error {
78 e := syscall.Exec(name, argv, envv)
80 return &PathError{"exec", name, Errno(e)}
85 // TODO(rsc): Should os implement its own syscall.WaitStatus
86 // wrapper with the methods, or is exposing the underlying one enough?
88 // TODO(rsc): Certainly need to have Rusage struct,
89 // since syscall one might have different field types across
92 // Waitmsg stores the information about an exited process as reported by Wait.
94 Pid int // The process's id.
95 syscall.WaitStatus // System-dependent status info.
96 Rusage *syscall.Rusage // System-dependent resource usage info.
99 // Wait waits for process pid to exit or stop, and then returns a
100 // Waitmsg describing its status and an Error, if any. The options
101 // (WNOHANG etc.) affect the behavior of the Wait call.
102 // Wait is equivalent to calling FindProcess and then Wait
103 // and Release on the result.
104 func Wait(pid int, options int) (w *Waitmsg, err Error) {
105 p, e := FindProcess(pid)
110 return p.Wait(options)
113 // Convert i to decimal string.
114 func itod(i int) string {
124 // Assemble decimal in reverse order.
127 for ; u > 0; u /= 10 {
129 b[bp] = byte(u%10) + '0'
137 return string(b[bp:])
140 func (w Waitmsg) String() string {
141 // TODO(austin) Use signal names when possible?
145 res = "exit status " + itod(w.ExitStatus())
147 res = "signal " + itod(w.Signal())
149 res = "stop signal " + itod(w.StopSignal())
150 if w.StopSignal() == syscall.SIGTRAP && w.TrapCause() != 0 {
151 res += " (trap " + itod(w.TrapCause()) + ")"
157 res += " (core dumped)"
162 // Getpid returns the process id of the caller.
163 func Getpid() int { return syscall.Getpid() }
165 // Getppid returns the process id of the caller's parent.
166 func Getppid() int { return syscall.Getppid() }