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.
15 func (p
*Process
) wait() (ps
*ProcessState
, err error
) {
16 s
, e
:= syscall
.WaitForSingleObject(syscall
.Handle(p
.handle
), syscall
.INFINITE
)
18 case syscall
.WAIT_OBJECT_0
:
20 case syscall
.WAIT_FAILED
:
21 return nil, NewSyscallError("WaitForSingleObject", e
)
23 return nil, errors
.New("os: unexpected result from WaitForSingleObject")
26 e
= syscall
.GetExitCodeProcess(syscall
.Handle(p
.handle
), &ec
)
28 return nil, NewSyscallError("GetExitCodeProcess", e
)
31 e
= syscall
.GetProcessTimes(syscall
.Handle(p
.handle
), &u
.CreationTime
, &u
.ExitTime
, &u
.KernelTime
, &u
.UserTime
)
33 return nil, NewSyscallError("GetProcessTimes", e
)
36 // NOTE(brainman): It seems that sometimes process is not dead
37 // when WaitForSingleObject returns. But we do not know any
38 // other way to wait for it. Sleeping for a while seems to do
39 // the trick sometimes. So we will sleep and smell the roses.
40 defer time
.Sleep(5 * time
.Millisecond
)
42 return &ProcessState
{p
.Pid
, syscall
.WaitStatus
{ExitCode
: ec
}, &u
}, nil
45 func terminateProcess(pid
, exitcode
int) error
{
46 h
, e
:= syscall
.OpenProcess(syscall
.PROCESS_TERMINATE
, false, uint32(pid
))
48 return NewSyscallError("OpenProcess", e
)
50 defer syscall
.CloseHandle(h
)
51 e
= syscall
.TerminateProcess(h
, uint32(exitcode
))
52 return NewSyscallError("TerminateProcess", e
)
55 func (p
*Process
) signal(sig Signal
) error
{
57 return errors
.New("os: process already finished")
60 return terminateProcess(p
.Pid
, 1)
62 // TODO(rsc): Handle Interrupt too?
63 return syscall
.Errno(syscall
.EWINDOWS
)
66 func (p
*Process
) release() error
{
67 if p
.handle
== uintptr(syscall
.InvalidHandle
) {
70 e
:= syscall
.CloseHandle(syscall
.Handle(p
.handle
))
72 return NewSyscallError("CloseHandle", e
)
74 p
.handle
= uintptr(syscall
.InvalidHandle
)
75 // no need for a finalizer anymore
76 runtime
.SetFinalizer(p
, nil)
80 func findProcess(pid
int) (p
*Process
, err error
) {
81 const da
= syscall
.STANDARD_RIGHTS_READ |
82 syscall
.PROCESS_QUERY_INFORMATION | syscall
.SYNCHRONIZE
83 h
, e
:= syscall
.OpenProcess(da
, false, uint32(pid
))
85 return nil, NewSyscallError("OpenProcess", e
)
87 return newProcess(pid
, uintptr(h
)), nil
92 cmd
:= syscall
.GetCommandLine()
93 argv
, e
:= syscall
.CommandLineToArgv(cmd
, &argc
)
97 defer syscall
.LocalFree(syscall
.Handle(uintptr(unsafe
.Pointer(argv
))))
98 Args
= make([]string, argc
)
99 for i
, v
:= range (*argv
)[:argc
] {
100 Args
[i
] = string(syscall
.UTF16ToString((*v
)[:]))
104 func ftToDuration(ft
*syscall
.Filetime
) time
.Duration
{
105 n
:= int64(ft
.HighDateTime
)<<32 + int64(ft
.LowDateTime
) // in 100-nanosecond intervals
106 return time
.Duration(n
*100) * time
.Nanosecond
109 func (p
*ProcessState
) userTime() time
.Duration
{
110 return ftToDuration(&p
.rusage
.UserTime
)
113 func (p
*ProcessState
) systemTime() time
.Duration
{
114 return ftToDuration(&p
.rusage
.KernelTime
)