github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/pkg/process/process_unix.go (about) 1 //go:build !windows 2 3 package process 4 5 import ( 6 "bytes" 7 "fmt" 8 "os" 9 "path/filepath" 10 "runtime" 11 "strconv" 12 13 "golang.org/x/sys/unix" 14 ) 15 16 // Alive returns true if process with a given pid is running. It only considers 17 // positive PIDs; 0 (all processes in the current process group), -1 (all processes 18 // with a PID larger than 1), and negative (-n, all processes in process group 19 // "n") values for pid are never considered to be alive. 20 func Alive(pid int) bool { 21 if pid < 1 { 22 return false 23 } 24 switch runtime.GOOS { 25 case "darwin": 26 // OS X does not have a proc filesystem. Use kill -0 pid to judge if the 27 // process exists. From KILL(2): https://www.freebsd.org/cgi/man.cgi?query=kill&sektion=2&manpath=OpenDarwin+7.2.1 28 // 29 // Sig may be one of the signals specified in sigaction(2) or it may 30 // be 0, in which case error checking is performed but no signal is 31 // actually sent. This can be used to check the validity of pid. 32 err := unix.Kill(pid, 0) 33 34 // Either the PID was found (no error) or we get an EPERM, which means 35 // the PID exists, but we don't have permissions to signal it. 36 return err == nil || err == unix.EPERM 37 default: 38 _, err := os.Stat(filepath.Join("/proc", strconv.Itoa(pid))) 39 return err == nil 40 } 41 } 42 43 // Kill force-stops a process. It only considers positive PIDs; 0 (all processes 44 // in the current process group), -1 (all processes with a PID larger than 1), 45 // and negative (-n, all processes in process group "n") values for pid are 46 // ignored. Refer to [KILL(2)] for details. 47 // 48 // [KILL(2)]: https://man7.org/linux/man-pages/man2/kill.2.html 49 func Kill(pid int) error { 50 if pid < 1 { 51 return fmt.Errorf("invalid PID (%d): only positive PIDs are allowed", pid) 52 } 53 err := unix.Kill(pid, unix.SIGKILL) 54 if err != nil && err != unix.ESRCH { 55 return err 56 } 57 return nil 58 } 59 60 // Zombie return true if process has a state with "Z". It only considers positive 61 // PIDs; 0 (all processes in the current process group), -1 (all processes with 62 // a PID larger than 1), and negative (-n, all processes in process group "n") 63 // values for pid are ignored. Refer to [PROC(5)] for details. 64 // 65 // [PROC(5)]: https://man7.org/linux/man-pages/man5/proc.5.html 66 func Zombie(pid int) (bool, error) { 67 if pid < 1 { 68 return false, nil 69 } 70 data, err := os.ReadFile(fmt.Sprintf("/proc/%d/stat", pid)) 71 if err != nil { 72 if os.IsNotExist(err) { 73 return false, nil 74 } 75 return false, err 76 } 77 if cols := bytes.SplitN(data, []byte(" "), 4); len(cols) >= 3 && string(cols[2]) == "Z" { 78 return true, nil 79 } 80 return false, nil 81 }