diff --git a/process/process.go b/process/process.go index a9d10e0..3866fae 100644 --- a/process/process.go +++ b/process/process.go @@ -139,21 +139,6 @@ func PidExists(pid int32) (bool, error) { return PidExistsWithContext(context.Background(), pid) } -func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) { - pids, err := Pids() - if err != nil { - return false, err - } - - for _, i := range pids { - if i == pid { - return true, err - } - } - - return false, err -} - // Background returns true if the process is in background, false otherwise. func (p *Process) Background() (bool, error) { return p.BackgroundWithContext(context.Background()) diff --git a/process/process_fallback.go b/process/process_fallback.go index 99c6573..afdb03e 100644 --- a/process/process_fallback.go +++ b/process/process_fallback.go @@ -48,6 +48,21 @@ func NewProcess(pid int32) (*Process, error) { return nil, common.ErrNotImplementedError } +func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) { + pids, err := PidsWithContext(ctx) + if err != nil { + return false, err + } + + for _, i := range pids { + if i == pid { + return true, err + } + } + + return false, err +} + func (p *Process) Ppid() (int32, error) { return p.PpidWithContext(context.Background()) } diff --git a/process/process_posix.go b/process/process_posix.go index 8ffb6b7..13f0308 100644 --- a/process/process_posix.go +++ b/process/process_posix.go @@ -4,6 +4,7 @@ package process import ( "context" + "fmt" "os" "os/user" "path/filepath" @@ -69,6 +70,34 @@ func getTerminalMap() (map[uint64]string, error) { return ret, nil } +func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) { + if pid <= 0 { + return false, fmt.Errorf("invalid pid %v", pid) + } + proc, err := os.FindProcess(int(pid)) + if err != nil { + return false, err + } + err = proc.Signal(syscall.Signal(0)) + if err == nil { + return true, nil + } + if err.Error() == "os: process already finished" { + return false, nil + } + errno, ok := err.(syscall.Errno) + if !ok { + return false, err + } + switch errno { + case syscall.ESRCH: + return false, nil + case syscall.EPERM: + return true, nil + } + return false, err +} + // SendSignal sends a unix.Signal to the process. // Currently, SIGSTOP, SIGCONT, SIGTERM and SIGKILL are supported. func (p *Process) SendSignal(sig syscall.Signal) error { diff --git a/process/process_windows.go b/process/process_windows.go index 96c3b1f..7a6d6b0 100644 --- a/process/process_windows.go +++ b/process/process_windows.go @@ -185,6 +185,21 @@ func PidsWithContext(ctx context.Context) ([]int32, error) { } +func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) { + pids, err := Pids() + if err != nil { + return false, err + } + + for _, i := range pids { + if i == pid { + return true, err + } + } + + return false, err +} + func (p *Process) Ppid() (int32, error) { return p.PpidWithContext(context.Background()) }