2
3
5
package os
7
import (
8
"errors"
9
"internal/syscall/windows"
10
"runtime"
11
"syscall"
12
"time"
13
)
15
16
18
func (p *Process) wait() (ps *ProcessState, err error) {
19
handle, status := p.handleTransientAcquire()
20
switch status {
21
case statusDone:
22
return nil, ErrProcessDone
23
case statusReleased:
24
return nil, syscall.EINVAL
25
}
26
defer p.handleTransientRelease()
28
s, e := syscall.WaitForSingleObject(syscall.Handle(handle), syscall.INFINITE)
29
switch s {
30
case syscall.WAIT_OBJECT_0:
31
break
32
case syscall.WAIT_FAILED:
33
return nil, NewSyscallError("WaitForSingleObject", e)
34
default:
35
return nil, errors.New("os: unexpected result from WaitForSingleObject")
36
}
37
var ec uint32
38
e = syscall.GetExitCodeProcess(syscall.Handle(handle), &ec)
39
if e != nil {
40
return nil, NewSyscallError("GetExitCodeProcess", e)
41
}
42
var u syscall.Rusage
43
e = syscall.GetProcessTimes(syscall.Handle(handle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime)
44
if e != nil {
45
return nil, NewSyscallError("GetProcessTimes", e)
46
}
47
defer p.Release()
48
return &ProcessState{p.Pid, syscall.WaitStatus{ExitCode: ec}, &u}, nil
49
}
51
func (p *Process) signal(sig Signal) error {
52
handle, status := p.handleTransientAcquire()
53
switch status {
54
case statusDone:
55
return ErrProcessDone
56
case statusReleased:
57
return syscall.EINVAL
58
}
59
defer p.handleTransientRelease()
61
if sig == Kill {
62
var terminationHandle syscall.Handle
63
e := syscall.DuplicateHandle(^syscall.Handle(0), syscall.Handle(handle), ^syscall.Handle(0), &terminationHandle, syscall.PROCESS_TERMINATE, false, 0)
64
if e != nil {
65
return NewSyscallError("DuplicateHandle", e)
66
}
67
runtime.KeepAlive(p)
68
defer syscall.CloseHandle(terminationHandle)
69
e = syscall.TerminateProcess(syscall.Handle(terminationHandle), 1)
70
return NewSyscallError("TerminateProcess", e)
71
}
72
73
return syscall.Errno(syscall.EWINDOWS)
74
}
76
func (p *Process) release() error {
77
78
79
80
81
82
if old := p.handlePersistentRelease(statusReleased); old == statusReleased {
83
return syscall.EINVAL
84
}
86
87
runtime.SetFinalizer(p, nil)
88
return nil
89
}
91
func (p *Process) closeHandle() {
92
syscall.CloseHandle(syscall.Handle(p.handle))
93
}
95
func findProcess(pid int) (p *Process, err error) {
96
const da = syscall.STANDARD_RIGHTS_READ |
97
syscall.PROCESS_QUERY_INFORMATION | syscall.SYNCHRONIZE
98
h, e := syscall.OpenProcess(da, false, uint32(pid))
99
if e != nil {
100
return nil, NewSyscallError("OpenProcess", e)
101
}
102
return newHandleProcess(pid, uintptr(h)), nil
103
}
105
func init() {
106
cmd := windows.UTF16PtrToString(syscall.GetCommandLine())
107
if len(cmd) == 0 {
108
arg0, _ := Executable()
109
Args = []string{arg0}
110
} else {
111
Args = commandLineToArgv(cmd)
112
}
113
}
115
116
func appendBSBytes(b []byte, n int) []byte {
117
for ; n > 0; n-- {
118
b = append(b, '\\')
119
}
120
return b
121
}
123
124
125
func readNextArg(cmd string) (arg []byte, rest string) {
126
var b []byte
127
var inquote bool
128
var nslash int
129
for ; len(cmd) > 0; cmd = cmd[1:] {
130
c := cmd[0]
131
switch c {
132
case ' ', '\t':
133
if !inquote {
134
return appendBSBytes(b, nslash), cmd[1:]
135
}
136
case '"':
137
b = appendBSBytes(b, nslash/2)
138
if nslash%2 == 0 {
139
140
141
142
if inquote && len(cmd) > 1 && cmd[1] == '"' {
143
b = append(b, c)
144
cmd = cmd[1:]
145
}
146
inquote = !inquote
147
} else {
148
b = append(b, c)
149
}
150
nslash = 0
151
continue
152
case '\\':
153
nslash++
154
continue
155
}
156
b = appendBSBytes(b, nslash)
157
nslash = 0
158
b = append(b, c)
159
}
160
return appendBSBytes(b, nslash), ""
161
}
163
164
165
166
func commandLineToArgv(cmd string) []string {
167
var args []string
168
for len(cmd) > 0 {
169
if cmd[0] == ' ' || cmd[0] == '\t' {
170
cmd = cmd[1:]
171
continue
172
}
173
var arg []byte
174
arg, cmd = readNextArg(cmd)
175
args = append(args, string(arg))
176
}
177
return args
178
}
180
func ftToDuration(ft *syscall.Filetime) time.Duration {
181
n := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime)
182
return time.Duration(n*100) * time.Nanosecond
183
}
185
func (p *ProcessState) userTime() time.Duration {
186
return ftToDuration(&p.rusage.UserTime)
187
}
189
func (p *ProcessState) systemTime() time.Duration {
190
return ftToDuration(&p.rusage.KernelTime)
191
}
View as plain text