2022-10-15 13:37:31 +00:00
|
|
|
//go:build !windows
|
2016-03-18 18:50:19 +00:00
|
|
|
|
2022-10-15 13:10:25 +00:00
|
|
|
package process
|
2016-03-18 18:50:19 +00:00
|
|
|
|
|
|
|
import (
|
2022-10-15 12:55:40 +00:00
|
|
|
"bytes"
|
2020-03-27 03:20:41 +00:00
|
|
|
"fmt"
|
2021-08-24 10:10:50 +00:00
|
|
|
"os"
|
2022-10-15 13:37:31 +00:00
|
|
|
"path/filepath"
|
|
|
|
"runtime"
|
|
|
|
"strconv"
|
2017-05-23 14:22:32 +00:00
|
|
|
|
|
|
|
"golang.org/x/sys/unix"
|
2016-03-18 18:50:19 +00:00
|
|
|
)
|
|
|
|
|
pkg/process: Alive(): fix PID 0, -1, negative values
unix.Kill() does not produce an error for PID 0, -1. As a result, checking
process.Alive() would return "true" for both 0 and -1 on macOS (and previously
on Linux as well).
Let's shortcut these values to consider them "not alive", to prevent someone
trying to kill them.
A basic test was added to check the behavior.
Given that the intent of these functions is to handle single processes, this patch
also prevents 0 and negative values to be used.
From KILL(2): https://man7.org/linux/man-pages/man2/kill.2.html
If pid is positive, then signal sig is sent to the process with
the ID specified by pid.
If pid equals 0, then sig is sent to every process in the process
group of the calling process.
If pid equals -1, then sig is sent to every process for which the
calling process has permission to send signals, except for
process 1 (init), but see below.
If pid is less than -1, then sig is sent to every process in the
process group whose ID is -pid.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-15 21:14:25 +00:00
|
|
|
// Alive returns true if process with a given pid is running. It only considers
|
|
|
|
// positive PIDs; 0 (all processes in the current process group), -1 (all processes
|
|
|
|
// with a PID larger than 1), and negative (-n, all processes in process group
|
|
|
|
// "n") values for pid are never considered to be alive.
|
2022-10-15 13:10:25 +00:00
|
|
|
func Alive(pid int) bool {
|
pkg/process: Alive(): fix PID 0, -1, negative values
unix.Kill() does not produce an error for PID 0, -1. As a result, checking
process.Alive() would return "true" for both 0 and -1 on macOS (and previously
on Linux as well).
Let's shortcut these values to consider them "not alive", to prevent someone
trying to kill them.
A basic test was added to check the behavior.
Given that the intent of these functions is to handle single processes, this patch
also prevents 0 and negative values to be used.
From KILL(2): https://man7.org/linux/man-pages/man2/kill.2.html
If pid is positive, then signal sig is sent to the process with
the ID specified by pid.
If pid equals 0, then sig is sent to every process in the process
group of the calling process.
If pid equals -1, then sig is sent to every process for which the
calling process has permission to send signals, except for
process 1 (init), but see below.
If pid is less than -1, then sig is sent to every process in the
process group whose ID is -pid.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-15 21:14:25 +00:00
|
|
|
if pid < 1 {
|
|
|
|
return false
|
|
|
|
}
|
2022-10-15 13:37:31 +00:00
|
|
|
switch runtime.GOOS {
|
|
|
|
case "darwin":
|
|
|
|
// OS X does not have a proc filesystem. Use kill -0 pid to judge if the
|
|
|
|
// process exists. From KILL(2): https://www.freebsd.org/cgi/man.cgi?query=kill&sektion=2&manpath=OpenDarwin+7.2.1
|
|
|
|
//
|
|
|
|
// Sig may be one of the signals specified in sigaction(2) or it may
|
|
|
|
// be 0, in which case error checking is performed but no signal is
|
|
|
|
// actually sent. This can be used to check the validity of pid.
|
|
|
|
err := unix.Kill(pid, 0)
|
2016-03-18 18:50:19 +00:00
|
|
|
|
2022-10-15 13:37:31 +00:00
|
|
|
// Either the PID was found (no error) or we get an EPERM, which means
|
|
|
|
// the PID exists, but we don't have permissions to signal it.
|
|
|
|
return err == nil || err == unix.EPERM
|
|
|
|
default:
|
|
|
|
_, err := os.Stat(filepath.Join("/proc", strconv.Itoa(pid)))
|
|
|
|
return err == nil
|
|
|
|
}
|
2016-03-18 18:50:19 +00:00
|
|
|
}
|
|
|
|
|
pkg/process: Alive(): fix PID 0, -1, negative values
unix.Kill() does not produce an error for PID 0, -1. As a result, checking
process.Alive() would return "true" for both 0 and -1 on macOS (and previously
on Linux as well).
Let's shortcut these values to consider them "not alive", to prevent someone
trying to kill them.
A basic test was added to check the behavior.
Given that the intent of these functions is to handle single processes, this patch
also prevents 0 and negative values to be used.
From KILL(2): https://man7.org/linux/man-pages/man2/kill.2.html
If pid is positive, then signal sig is sent to the process with
the ID specified by pid.
If pid equals 0, then sig is sent to every process in the process
group of the calling process.
If pid equals -1, then sig is sent to every process for which the
calling process has permission to send signals, except for
process 1 (init), but see below.
If pid is less than -1, then sig is sent to every process in the
process group whose ID is -pid.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-15 21:14:25 +00:00
|
|
|
// Kill force-stops a process. It only considers positive PIDs; 0 (all processes
|
|
|
|
// in the current process group), -1 (all processes with a PID larger than 1),
|
|
|
|
// and negative (-n, all processes in process group "n") values for pid are
|
|
|
|
// ignored. Refer to [KILL(2)] for details.
|
|
|
|
//
|
|
|
|
// [KILL(2)]: https://man7.org/linux/man-pages/man2/kill.2.html
|
2022-10-15 13:10:25 +00:00
|
|
|
func Kill(pid int) error {
|
pkg/process: Alive(): fix PID 0, -1, negative values
unix.Kill() does not produce an error for PID 0, -1. As a result, checking
process.Alive() would return "true" for both 0 and -1 on macOS (and previously
on Linux as well).
Let's shortcut these values to consider them "not alive", to prevent someone
trying to kill them.
A basic test was added to check the behavior.
Given that the intent of these functions is to handle single processes, this patch
also prevents 0 and negative values to be used.
From KILL(2): https://man7.org/linux/man-pages/man2/kill.2.html
If pid is positive, then signal sig is sent to the process with
the ID specified by pid.
If pid equals 0, then sig is sent to every process in the process
group of the calling process.
If pid equals -1, then sig is sent to every process for which the
calling process has permission to send signals, except for
process 1 (init), but see below.
If pid is less than -1, then sig is sent to every process in the
process group whose ID is -pid.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-15 21:14:25 +00:00
|
|
|
if pid < 1 {
|
|
|
|
return fmt.Errorf("invalid PID (%d): only positive PIDs are allowed", pid)
|
|
|
|
}
|
2022-10-15 13:10:25 +00:00
|
|
|
err := unix.Kill(pid, unix.SIGKILL)
|
|
|
|
if err != nil && err != unix.ESRCH {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
2016-03-18 18:50:19 +00:00
|
|
|
}
|
2020-03-27 03:20:41 +00:00
|
|
|
|
pkg/process: Alive(): fix PID 0, -1, negative values
unix.Kill() does not produce an error for PID 0, -1. As a result, checking
process.Alive() would return "true" for both 0 and -1 on macOS (and previously
on Linux as well).
Let's shortcut these values to consider them "not alive", to prevent someone
trying to kill them.
A basic test was added to check the behavior.
Given that the intent of these functions is to handle single processes, this patch
also prevents 0 and negative values to be used.
From KILL(2): https://man7.org/linux/man-pages/man2/kill.2.html
If pid is positive, then signal sig is sent to the process with
the ID specified by pid.
If pid equals 0, then sig is sent to every process in the process
group of the calling process.
If pid equals -1, then sig is sent to every process for which the
calling process has permission to send signals, except for
process 1 (init), but see below.
If pid is less than -1, then sig is sent to every process in the
process group whose ID is -pid.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-15 21:14:25 +00:00
|
|
|
// Zombie return true if process has a state with "Z". It only considers positive
|
|
|
|
// PIDs; 0 (all processes in the current process group), -1 (all processes with
|
|
|
|
// a PID larger than 1), and negative (-n, all processes in process group "n")
|
|
|
|
// values for pid are ignored. Refer to [PROC(5)] for details.
|
|
|
|
//
|
|
|
|
// [PROC(5)]: https://man7.org/linux/man-pages/man5/proc.5.html
|
2022-10-15 13:10:25 +00:00
|
|
|
func Zombie(pid int) (bool, error) {
|
pkg/process: Alive(): fix PID 0, -1, negative values
unix.Kill() does not produce an error for PID 0, -1. As a result, checking
process.Alive() would return "true" for both 0 and -1 on macOS (and previously
on Linux as well).
Let's shortcut these values to consider them "not alive", to prevent someone
trying to kill them.
A basic test was added to check the behavior.
Given that the intent of these functions is to handle single processes, this patch
also prevents 0 and negative values to be used.
From KILL(2): https://man7.org/linux/man-pages/man2/kill.2.html
If pid is positive, then signal sig is sent to the process with
the ID specified by pid.
If pid equals 0, then sig is sent to every process in the process
group of the calling process.
If pid equals -1, then sig is sent to every process for which the
calling process has permission to send signals, except for
process 1 (init), but see below.
If pid is less than -1, then sig is sent to every process in the
process group whose ID is -pid.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-15 21:14:25 +00:00
|
|
|
if pid < 1 {
|
|
|
|
return false, nil
|
|
|
|
}
|
2022-10-15 12:55:40 +00:00
|
|
|
data, err := os.ReadFile(fmt.Sprintf("/proc/%d/stat", pid))
|
2020-03-27 03:20:41 +00:00
|
|
|
if err != nil {
|
2022-10-15 12:50:48 +00:00
|
|
|
if os.IsNotExist(err) {
|
|
|
|
return false, nil
|
|
|
|
}
|
2020-03-27 03:20:41 +00:00
|
|
|
return false, err
|
|
|
|
}
|
2022-10-15 12:55:40 +00:00
|
|
|
if cols := bytes.SplitN(data, []byte(" "), 4); len(cols) >= 3 && string(cols[2]) == "Z" {
|
2020-03-27 03:20:41 +00:00
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
return false, nil
|
|
|
|
}
|