LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package os | 5 package os |
6 | 6 |
7 import ( | 7 import ( |
| 8 "runtime" |
8 "syscall" | 9 "syscall" |
9 ) | 10 ) |
10 | 11 |
11 // Process stores the information about monitored os process. | 12 // Process stores the information about a process created by StartProcess. |
12 type Process struct { | 13 type Process struct { |
13 Pid int | 14 Pid int |
14 handle int | 15 handle int |
15 } | 16 } |
16 | 17 |
17 // StartProcess starts new process with the program, arguments, | 18 func newProcess(pid, handle int) *Process { |
18 // and environment specified by name, argv, and envv. If successful, Wait metho
d on | 19 » p := &Process{pid, handle} |
19 // the retuned Process can be used to wait for new process to exit and retrieve | 20 » runtime.SetFinalizer(p, (*Process).Release) |
20 // exit reason. StartProcess also returns Error, if any. The fd array specifies
the | 21 » return p |
| 22 } |
| 23 |
| 24 // StartProcess starts a new process with the program, arguments, |
| 25 // and environment specified by name, argv, and envv. The fd array specifies the |
21 // file descriptors to be set up in the new process: fd[0] will be Unix file | 26 // file descriptors to be set up in the new process: fd[0] will be Unix file |
22 // descriptor 0 (standard input), fd[1] descriptor 1, and so on. A nil entry | 27 // descriptor 0 (standard input), fd[1] descriptor 1, and so on. A nil entry |
23 // will cause the child to have no open file descriptor with that index. | 28 // will cause the child to have no open file descriptor with that index. |
24 // If dir is not empty, the child chdirs into the directory before execing the p
rogram. | 29 // If dir is not empty, the child chdirs into the directory before execing the p
rogram. |
25 func StartProcess(name string, argv []string, envv []string, dir string, fd []*F
ile) (p *Process, err Error) { | 30 func StartProcess(name string, argv []string, envv []string, dir string, fd []*F
ile) (p *Process, err Error) { |
26 if envv == nil { | 31 if envv == nil { |
27 envv = Environ() | 32 envv = Environ() |
28 } | 33 } |
29 // Create array of integer (system) fds. | 34 // Create array of integer (system) fds. |
30 intfd := make([]int, len(fd)) | 35 intfd := make([]int, len(fd)) |
31 for i, f := range fd { | 36 for i, f := range fd { |
32 if f == nil { | 37 if f == nil { |
33 intfd[i] = -1 | 38 intfd[i] = -1 |
34 } else { | 39 } else { |
35 intfd[i] = f.Fd() | 40 intfd[i] = f.Fd() |
36 } | 41 } |
37 } | 42 } |
38 | 43 |
39 pid, h, e := syscall.StartProcess(name, argv, envv, dir, intfd) | 44 pid, h, e := syscall.StartProcess(name, argv, envv, dir, intfd) |
40 if e != 0 { | 45 if e != 0 { |
41 return nil, &PathError{"fork/exec", name, Errno(e)} | 46 return nil, &PathError{"fork/exec", name, Errno(e)} |
42 } | 47 } |
43 » return &Process{pid, h}, nil | 48 » return newProcess(pid, h), nil |
44 } | |
45 | |
46 // ForkExec is deprecated and will be removed after the next release. | |
47 func ForkExec(name string, argv []string, envv []string, dir string, fd []*File)
(pid int, err Error) { | |
48 » p, e := StartProcess(name, argv, envv, dir, fd) | |
49 » if e != nil { | |
50 » » return 0, e | |
51 » } | |
52 » defer p.Close() | |
53 » return p.Pid, nil | |
54 } | 49 } |
55 | 50 |
56 // Exec replaces the current process with an execution of the | 51 // Exec replaces the current process with an execution of the |
57 // named binary, with arguments argv and environment envv. | 52 // named binary, with arguments argv and environment envv. |
58 // If successful, Exec never returns. If it fails, it returns an Error. | 53 // If successful, Exec never returns. If it fails, it returns an Error. |
59 // StartProcess is almost always a better way to execute a program. | 54 // StartProcess is almost always a better way to execute a program. |
60 func Exec(name string, argv []string, envv []string) Error { | 55 func Exec(name string, argv []string, envv []string) Error { |
61 if envv == nil { | 56 if envv == nil { |
62 envv = Environ() | 57 envv = Environ() |
63 } | 58 } |
(...skipping 14 matching lines...) Expand all Loading... |
78 // Waitmsg stores the information about an exited process as reported by Wait. | 73 // Waitmsg stores the information about an exited process as reported by Wait. |
79 type Waitmsg struct { | 74 type Waitmsg struct { |
80 Pid int // The process's id. | 75 Pid int // The process's id. |
81 syscall.WaitStatus // System-dependent status info. | 76 syscall.WaitStatus // System-dependent status info. |
82 Rusage *syscall.Rusage // System-dependent resource usage in
fo. | 77 Rusage *syscall.Rusage // System-dependent resource usage in
fo. |
83 } | 78 } |
84 | 79 |
85 // Wait waits for process pid to exit or stop, and then returns a | 80 // Wait waits for process pid to exit or stop, and then returns a |
86 // Waitmsg describing its status and an Error, if any. The options | 81 // Waitmsg describing its status and an Error, if any. The options |
87 // (WNOHANG etc.) affect the behavior of the Wait call. | 82 // (WNOHANG etc.) affect the behavior of the Wait call. |
88 // Just a shortcut for os.FindProcess() + (*Process).Wait() + (*Process).Close()
. | 83 // Wait is equivalent to calling FindProcess and then Wait |
| 84 // and Release on the result. |
89 func Wait(pid int, options int) (w *Waitmsg, err Error) { | 85 func Wait(pid int, options int) (w *Waitmsg, err Error) { |
90 p, e := FindProcess(pid) | 86 p, e := FindProcess(pid) |
91 if e != nil { | 87 if e != nil { |
92 return nil, e | 88 return nil, e |
93 } | 89 } |
94 » defer p.Close() | 90 » defer p.Release() |
95 » return p.Wait(0) | 91 » return p.Wait(options) |
96 } | 92 } |
97 | 93 |
98 // Convert i to decimal string. | 94 // Convert i to decimal string. |
99 func itod(i int) string { | 95 func itod(i int) string { |
100 if i == 0 { | 96 if i == 0 { |
101 return "0" | 97 return "0" |
102 } | 98 } |
103 | 99 |
104 u := uint64(i) | 100 u := uint64(i) |
105 if i < 0 { | 101 if i < 0 { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 res += " (core dumped)" | 138 res += " (core dumped)" |
143 } | 139 } |
144 return res | 140 return res |
145 } | 141 } |
146 | 142 |
147 // Getpid returns the process id of the caller. | 143 // Getpid returns the process id of the caller. |
148 func Getpid() int { return syscall.Getpid() } | 144 func Getpid() int { return syscall.Getpid() } |
149 | 145 |
150 // Getppid returns the process id of the caller's parent. | 146 // Getppid returns the process id of the caller's parent. |
151 func Getppid() int { return syscall.Getppid() } | 147 func Getppid() int { return syscall.Getppid() } |
LEFT | RIGHT |