diff options
Diffstat (limited to 'libgo/go/os/exec_windows.go')
-rw-r--r-- | libgo/go/os/exec_windows.go | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/libgo/go/os/exec_windows.go b/libgo/go/os/exec_windows.go index 9463d2c0e3f..5beca4a6509 100644 --- a/libgo/go/os/exec_windows.go +++ b/libgo/go/os/exec_windows.go @@ -8,12 +8,11 @@ import ( "errors" "runtime" "syscall" + "time" "unsafe" ) -// Wait waits for the Process to exit or stop, and then returns a -// Waitmsg describing its status and an error, if any. -func (p *Process) Wait(options int) (w *Waitmsg, err error) { +func (p *Process) wait() (ps *ProcessState, err error) { s, e := syscall.WaitForSingleObject(syscall.Handle(p.handle), syscall.INFINITE) switch s { case syscall.WAIT_OBJECT_0: @@ -28,26 +27,36 @@ func (p *Process) Wait(options int) (w *Waitmsg, err error) { if e != nil { return nil, NewSyscallError("GetExitCodeProcess", e) } + var u syscall.Rusage + e = syscall.GetProcessTimes(syscall.Handle(p.handle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime) + if e != nil { + return nil, NewSyscallError("GetProcessTimes", e) + } p.done = true - return &Waitmsg{p.Pid, syscall.WaitStatus{Status: s, ExitCode: ec}, new(syscall.Rusage)}, nil + // NOTE(brainman): It seems that sometimes process is not dead + // when WaitForSingleObject returns. But we do not know any + // other way to wait for it. Sleeping for a while seems to do + // the trick sometimes. So we will sleep and smell the roses. + defer time.Sleep(5 * time.Millisecond) + defer p.Release() + return &ProcessState{p.Pid, syscall.WaitStatus{ExitCode: ec}, &u}, nil } -// Signal sends a signal to the Process. -func (p *Process) Signal(sig Signal) error { +func (p *Process) signal(sig Signal) error { if p.done { return errors.New("os: process already finished") } - if us, ok := sig.(UnixSignal); ok && us == syscall.SIGKILL { + if sig == Kill { e := syscall.TerminateProcess(syscall.Handle(p.handle), 1) return NewSyscallError("TerminateProcess", e) } + // TODO(rsc): Handle Interrupt too? return syscall.Errno(syscall.EWINDOWS) } -// Release releases any resources associated with the Process. -func (p *Process) Release() error { +func (p *Process) release() error { if p.handle == uintptr(syscall.InvalidHandle) { - return EINVAL + return syscall.EINVAL } e := syscall.CloseHandle(syscall.Handle(p.handle)) if e != nil { @@ -82,3 +91,16 @@ func init() { Args[i] = string(syscall.UTF16ToString((*v)[:])) } } + +func ftToDuration(ft *syscall.Filetime) time.Duration { + n := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) // in 100-nanosecond intervals + return time.Duration(n*100) * time.Nanosecond +} + +func (p *ProcessState) userTime() time.Duration { + return ftToDuration(&p.rusage.UserTime) +} + +func (p *ProcessState) systemTime() time.Duration { + return ftToDuration(&p.rusage.KernelTime) +} |