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 (p *Process) signal(sig Signal) error {
47 return errors.New("os: process already finished")
50 e := syscall.TerminateProcess(syscall.Handle(p.handle), 1)
51 return NewSyscallError("TerminateProcess", e)
53 // TODO(rsc): Handle Interrupt too?
54 return syscall.Errno(syscall.EWINDOWS)
57 func (p *Process) release() error {
58 if p.handle == uintptr(syscall.InvalidHandle) {
61 e := syscall.CloseHandle(syscall.Handle(p.handle))
63 return NewSyscallError("CloseHandle", e)
65 p.handle = uintptr(syscall.InvalidHandle)
66 // no need for a finalizer anymore
67 runtime.SetFinalizer(p, nil)
71 func findProcess(pid int) (p *Process, err error) {
72 const da = syscall.STANDARD_RIGHTS_READ |
73 syscall.PROCESS_QUERY_INFORMATION | syscall.SYNCHRONIZE
74 h, e := syscall.OpenProcess(da, false, uint32(pid))
76 return nil, NewSyscallError("OpenProcess", e)
78 return newProcess(pid, uintptr(h)), nil
83 cmd := syscall.GetCommandLine()
84 argv, e := syscall.CommandLineToArgv(cmd, &argc)
88 defer syscall.LocalFree(syscall.Handle(uintptr(unsafe.Pointer(argv))))
89 Args = make([]string, argc)
90 for i, v := range (*argv)[:argc] {
91 Args[i] = string(syscall.UTF16ToString((*v)[:]))
95 func ftToDuration(ft *syscall.Filetime) time.Duration {
96 n := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) // in 100-nanosecond intervals
97 return time.Duration(n*100) * time.Nanosecond
100 func (p *ProcessState) userTime() time.Duration {
101 return ftToDuration(&p.rusage.UserTime)
104 func (p *ProcessState) systemTime() time.Duration {
105 return ftToDuration(&p.rusage.KernelTime)