func (process *jobProcess) Wait() (int, error) { s, e := syscall.WaitForSingleObject(syscall.Handle(process.processHandle), syscall.INFINITE) switch s { case syscall.WAIT_OBJECT_0: break case syscall.WAIT_FAILED: return -1, os.NewSyscallError("WaitForSingleObject", e) default: return -1, errors.New("os: unexpected result from WaitForSingleObject") } var ec uint32 e = syscall.GetExitCodeProcess(syscall.Handle(process.processHandle), &ec) if e != nil { return -1, os.NewSyscallError("GetExitCodeProcess", e) } var u syscall.Rusage e = syscall.GetProcessTimes(syscall.Handle(process.processHandle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime) if e != nil { return -1, os.NewSyscallError("GetProcessTimes", e) } // 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 syscall.CloseHandle(syscall.Handle(process.processHandle)) return int(ec), nil }
func (p *Process) wait() (ps *ProcessState, err error) { handle := atomic.LoadUintptr(&p.handle) s, e := syscall.WaitForSingleObject(syscall.Handle(handle), syscall.INFINITE) switch s { case syscall.WAIT_OBJECT_0: break case syscall.WAIT_FAILED: return nil, NewSyscallError("WaitForSingleObject", e) default: return nil, errors.New("os: unexpected result from WaitForSingleObject") } var ec uint32 e = syscall.GetExitCodeProcess(syscall.Handle(handle), &ec) if e != nil { return nil, NewSyscallError("GetExitCodeProcess", e) } var u syscall.Rusage e = syscall.GetProcessTimes(syscall.Handle(handle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime) if e != nil { return nil, NewSyscallError("GetProcessTimes", e) } p.setDone() // 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 }
func (sub *Subprocess) BottomHalf(d *SubprocessData, sig chan *SubprocessResult) { hProcess := d.platformData.hProcess hJob := d.platformData.hJob result := &SubprocessResult{} var waitResult uint32 waitResult = syscall.WAIT_TIMEOUT var runState runningState for result.SuccessCode == 0 && waitResult == syscall.WAIT_TIMEOUT { waitResult, _ = syscall.WaitForSingleObject(hProcess, uint32(sub.TimeQuantum.Nanoseconds()/1000000)) if waitResult != syscall.WAIT_TIMEOUT { break } _ = UpdateProcessTimes(&d.platformData, result, false) if sub.MemoryLimit > 0 { UpdateProcessMemory(&d.platformData, result) } runState.Update(sub, result) } switch waitResult { case syscall.WAIT_OBJECT_0: _ = syscall.GetExitCodeProcess(hProcess, &result.ExitCode) case syscall.WAIT_TIMEOUT: for waitResult == syscall.WAIT_TIMEOUT { syscall.TerminateProcess(hProcess, 0) waitResult, _ = syscall.WaitForSingleObject(hProcess, 100) } } _ = UpdateProcessTimes(&d.platformData, result, true) UpdateProcessMemory(&d.platformData, result) syscall.CloseHandle(hProcess) if hJob != syscall.InvalidHandle { syscall.CloseHandle(hJob) } sub.SetPostLimits(result) for _ = range d.startAfterStart { err := <-d.bufferChan if err != nil { log.Error(err) } } if d.stdOut.Len() > 0 { result.Output = d.stdOut.Bytes() } if d.stdErr.Len() > 0 { result.Error = d.stdErr.Bytes() } sig <- result }
func processExists(pid int) bool { h, err := syscall.OpenProcess(processQueryLimitedInformation, false, uint32(pid)) if err != nil { return false } var c uint32 err = syscall.GetExitCodeProcess(h, &c) syscall.Close(h) if err != nil { return c == stillActive } return true }
// _pidAlive tests whether a process is alive or not func _pidAlive(pid int) bool { h, err := syscall.OpenProcess(processDesiredAccess, false, uint32(pid)) if err != nil { return false } var ec uint32 if e := syscall.GetExitCodeProcess(h, &ec); e != nil { return false } return ec == exit_STILL_ACTIVE }
func (s *Spawner) Alive() bool { const da = syscall.STANDARD_RIGHTS_READ | syscall.PROCESS_QUERY_INFORMATION | syscall.SYNCHRONIZE h, e := syscall.OpenProcess(da, false, uint32(s.SpawnPid)) if e != nil { return false } var ec uint32 e = syscall.GetExitCodeProcess(h, &ec) if e != nil { return false } return ec == STILL_ACTIVE }
func (p *Process) Wait(options int) (w *Waitmsg, err Error) { s, e := syscall.WaitForSingleObject(int32(p.handle), syscall.INFINITE) switch s { case syscall.WAIT_OBJECT_0: break case syscall.WAIT_FAILED: return nil, NewSyscallError("WaitForSingleObject", e) default: return nil, ErrorString("os: unexpected result from WaitForSingleObject") } var ec uint32 e = syscall.GetExitCodeProcess(uint32(p.handle), &ec) if e != 0 { return nil, NewSyscallError("GetExitCodeProcess", e) } return &Waitmsg{p.Pid, syscall.WaitStatus{s, ec}, new(syscall.Rusage)}, nil }
// Wait waits for the Process to exit or stop, and then returns a // ProcessState describing its status and an error, if any. 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: break case syscall.WAIT_FAILED: return nil, NewSyscallError("WaitForSingleObject", e) default: return nil, errors.New("os: unexpected result from WaitForSingleObject") } var ec uint32 e = syscall.GetExitCodeProcess(syscall.Handle(p.handle), &ec) if e != nil { return nil, NewSyscallError("GetExitCodeProcess", e) } p.done = true return &ProcessState{p.Pid, syscall.WaitStatus{Status: s, ExitCode: ec}, new(syscall.Rusage)}, nil }
func isRunning(pid int) (bool, error) { procHnd, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, true, uint32(pid)) if err != nil { if scerr, ok := err.(syscall.Errno); ok { if uintptr(scerr) == error_invalid_parameter { return false, nil } } } var code uint32 err = syscall.GetExitCodeProcess(procHnd, &code) if err != nil { return false, err } return code == code_still_active, nil }
// getProcStatus returns the status of a process. func getProcStatus(pid int) (RunState, error) { handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid)) if err != nil { return RunStateUnknown, errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) } defer syscall.CloseHandle(handle) var exitCode uint32 err = syscall.GetExitCodeProcess(handle, &exitCode) if err != nil { return RunStateUnknown, errors.Wrapf(err, "GetExitCodeProcess failed for pid=%v") } if exitCode == 259 { //still active return RunStateRun, nil } return RunStateSleep, nil }
func GetProcStatus(pid int) (RunState, error) { handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) defer syscall.CloseHandle(handle) if err != nil { return RunStateUnknown, fmt.Errorf("OpenProcess fails with %v", err) } var ec uint32 e := syscall.GetExitCodeProcess(syscall.Handle(handle), &ec) if e != nil { return RunStateUnknown, os.NewSyscallError("GetExitCodeProcess", e) } if ec == 259 { //still active return RunStateRun, nil } return RunStateSleep, nil }
func isProcessAlive(p *os.Process) error { // Extract handle value from the os.Process struct to avoid the need // of a second, manually opened process handle. value := reflect.ValueOf(p) // Dereference *os.Process to os.Process value = value.Elem() field := value.FieldByName("handle") handle := syscall.Handle(field.Uint()) var code uint32 err := syscall.GetExitCodeProcess(handle, &code) if err != nil { return err } // code will contain the exit code of the process or 259 (STILL_ALIVE) // if the process has not exited yet. if code == 259 { return nil } return ErrDeadOwner }
func GetExitCodeProcess(proc *os.Process) (uint32, error) { handle := GetProcessHandle(proc) var _exit uint32 err := syscall.GetExitCodeProcess(syscall.Handle(handle), &_exit) return _exit, err }