LEFT | RIGHT |
(no file at all) | |
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 // +build darwin freebsd linux openbsd | 5 // +build darwin freebsd linux openbsd |
6 | 6 |
7 package os | 7 package os |
8 | 8 |
9 import ( | 9 import ( |
| 10 "errors" |
10 "runtime" | 11 "runtime" |
11 "syscall" | 12 "syscall" |
12 ) | 13 ) |
13 | 14 |
14 // Options for Wait. | 15 // Options for Wait. |
15 const ( | 16 const ( |
16 WNOHANG = syscall.WNOHANG // Don't wait if no process has exited. | 17 WNOHANG = syscall.WNOHANG // Don't wait if no process has exited. |
17 WSTOPPED = syscall.WSTOPPED // If set, status of stopped subprocesses
is also reported. | 18 WSTOPPED = syscall.WSTOPPED // If set, status of stopped subprocesses
is also reported. |
18 WUNTRACED = syscall.WUNTRACED // Usually an alias for WSTOPPED. | 19 WUNTRACED = syscall.WUNTRACED // Usually an alias for WSTOPPED. |
19 WRUSAGE = 1 << 20 // Record resource usage. | 20 WRUSAGE = 1 << 20 // Record resource usage. |
20 ) | 21 ) |
21 | 22 |
22 // WRUSAGE must not be too high a bit, to avoid clashing with Linux's | 23 // WRUSAGE must not be too high a bit, to avoid clashing with Linux's |
23 // WCLONE, WALL, and WNOTHREAD flags, which sit in the top few bits of | 24 // WCLONE, WALL, and WNOTHREAD flags, which sit in the top few bits of |
24 // the options | 25 // the options |
25 | 26 |
26 // Wait waits for the Process to exit or stop, and then returns a | 27 // Wait waits for the Process to exit or stop, and then returns a |
27 // Waitmsg describing its status and an Error, if any. The options | 28 // Waitmsg describing its status and an error, if any. The options |
28 // (WNOHANG etc.) affect the behavior of the Wait call. | 29 // (WNOHANG etc.) affect the behavior of the Wait call. |
29 func (p *Process) Wait(options int) (w *Waitmsg, err Error) { | 30 func (p *Process) Wait(options int) (w *Waitmsg, err error) { |
30 if p.Pid == -1 { | 31 if p.Pid == -1 { |
31 return nil, EINVAL | 32 return nil, EINVAL |
32 } | 33 } |
33 var status syscall.WaitStatus | 34 var status syscall.WaitStatus |
34 var rusage *syscall.Rusage | 35 var rusage *syscall.Rusage |
35 if options&WRUSAGE != 0 { | 36 if options&WRUSAGE != 0 { |
36 rusage = new(syscall.Rusage) | 37 rusage = new(syscall.Rusage) |
37 options ^= WRUSAGE | 38 options ^= WRUSAGE |
38 } | 39 } |
39 pid1, e := syscall.Wait4(p.Pid, &status, options, rusage) | 40 pid1, e := syscall.Wait4(p.Pid, &status, options, rusage) |
40 if e != 0 { | 41 if e != 0 { |
41 return nil, NewSyscallError("wait", e) | 42 return nil, NewSyscallError("wait", e) |
42 } | 43 } |
43 // With WNOHANG pid is 0 if child has not exited. | 44 // With WNOHANG pid is 0 if child has not exited. |
44 if pid1 != 0 && options&WSTOPPED == 0 { | 45 if pid1 != 0 && options&WSTOPPED == 0 { |
45 p.done = true | 46 p.done = true |
46 } | 47 } |
47 w = new(Waitmsg) | 48 w = new(Waitmsg) |
48 w.Pid = pid1 | 49 w.Pid = pid1 |
49 w.WaitStatus = status | 50 w.WaitStatus = status |
50 w.Rusage = rusage | 51 w.Rusage = rusage |
51 return w, nil | 52 return w, nil |
52 } | 53 } |
53 | 54 |
54 // Signal sends a signal to the Process. | 55 // Signal sends a signal to the Process. |
55 func (p *Process) Signal(sig Signal) Error { | 56 func (p *Process) Signal(sig Signal) error { |
56 if p.done { | 57 if p.done { |
57 » » return NewError("os: process already finished") | 58 » » return errors.New("os: process already finished") |
58 } | 59 } |
59 if e := syscall.Kill(p.Pid, int(sig.(UnixSignal))); e != 0 { | 60 if e := syscall.Kill(p.Pid, int(sig.(UnixSignal))); e != 0 { |
60 return Errno(e) | 61 return Errno(e) |
61 } | 62 } |
62 return nil | 63 return nil |
63 } | 64 } |
64 | 65 |
65 // Release releases any resources associated with the Process. | 66 // Release releases any resources associated with the Process. |
66 func (p *Process) Release() Error { | 67 func (p *Process) Release() error { |
67 // NOOP for unix. | 68 // NOOP for unix. |
68 p.Pid = -1 | 69 p.Pid = -1 |
69 // no need for a finalizer anymore | 70 // no need for a finalizer anymore |
70 runtime.SetFinalizer(p, nil) | 71 runtime.SetFinalizer(p, nil) |
71 return nil | 72 return nil |
72 } | 73 } |
73 | 74 |
74 // FindProcess looks for a running process by its pid. | 75 // FindProcess looks for a running process by its pid. |
75 // The Process it returns can be used to obtain information | 76 // The Process it returns can be used to obtain information |
76 // about the underlying operating system process. | 77 // about the underlying operating system process. |
77 func FindProcess(pid int) (p *Process, err Error) { | 78 func FindProcess(pid int) (p *Process, err error) { |
78 // NOOP for unix. | 79 // NOOP for unix. |
79 return newProcess(pid, 0), nil | 80 return newProcess(pid, 0), nil |
80 } | 81 } |
LEFT | RIGHT |