예제 #1
0
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
}
예제 #2
0
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
}
예제 #3
0
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
}
예제 #4
0
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
}
예제 #5
0
// _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
}
예제 #6
0
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
}
예제 #7
0
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
}
예제 #8
0
파일: exec_windows.go 프로젝트: tav/go
// 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
}
예제 #9
0
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
}
예제 #10
0
// 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
}
예제 #11
0
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
}
예제 #12
0
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
}
예제 #13
0
func GetExitCodeProcess(proc *os.Process) (uint32, error) {
	handle := GetProcessHandle(proc)
	var _exit uint32
	err := syscall.GetExitCodeProcess(syscall.Handle(handle), &_exit)
	return _exit, err
}