dcavalca / rpms / util-linux

Forked from rpms/util-linux a year ago
Clone
5019b5
diff -Naur a/misc-utils/kill.1 b/misc-utils/kill.1
5019b5
--- a/misc-utils/kill.1	2018-07-11 06:34:54.235003686 -0700
5019b5
+++ b/misc-utils/kill.1	2022-12-07 16:19:17.911880263 -0800
5019b5
@@ -99,6 +99,8 @@
5019b5
 \fB\-p\fR, \fB\-\-pid\fR
5019b5
 Only print the process ID (PID) of the named processes, do not send any
5019b5
 signals.
5019b5
+\fB\-r\fR, \fB\-\-require\-handler\fR
5019b5
+Do not send the signal if it is not caught in userspace by the signalled process.
5019b5
 .TP
5019b5
 \fB\-\-verbose\fR
5019b5
 Print PID(s) that will be signaled with kill along with the signal.
5019b5
diff -Naur a/misc-utils/kill.c b/misc-utils/kill.c
5019b5
--- a/misc-utils/kill.c	2018-06-04 00:57:02.809445758 -0700
5019b5
+++ b/misc-utils/kill.c	2022-12-07 16:21:16.372629866 -0800
5019b5
@@ -79,6 +79,7 @@
5019b5
 		check_all:1,
5019b5
 		do_kill:1,
5019b5
 		do_pid:1,
5019b5
+		require_handler:1,
5019b5
 		use_sigval:1,
5019b5
 		verbose:1;
5019b5
 };
5019b5
@@ -188,6 +189,7 @@
5019b5
 	fputs(_(" -p, --pid              print pids without signaling them\n"), out);
5019b5
 	fputs(_(" -l, --list[=<signal>]  list signal names, or convert a signal number to a name\n"), out);
5019b5
 	fputs(_(" -L, --table            list signal names and numbers\n"), out);
5019b5
+	fputs(_(" -r, --require-handler  do not send signal if signal handler is not present\n"), out);
5019b5
 	fputs(_("     --verbose          print pids that will be signaled\n"), out);
5019b5
 
5019b5
 	fputs(USAGE_SEPARATOR, out);
5019b5
@@ -254,6 +256,10 @@
5019b5
 			print_all_signals(stdout, 1);
5019b5
 			exit(EXIT_SUCCESS);
5019b5
 		}
5019b5
+		if (!strcmp(arg, "-r") || !strcmp(arg, "--require-handler")) {
5019b5
+			ctl->require_handler = 1;
5019b5
+			continue;
5019b5
+		}
5019b5
 		if (!strcmp(arg, "-p") || !strcmp(arg, "--pid")) {
5019b5
 			ctl->do_pid = 1;
5019b5
 			if (ctl->do_kill)
5019b5
@@ -335,6 +341,32 @@
5019b5
 	return rc;
5019b5
 }
5019b5
 
5019b5
+static int check_signal_handler(const struct kill_control *ctl)
5019b5
+{
5019b5
+	uintmax_t sigcgt = 0;
5019b5
+	int rc = 0, has_hnd = 0;
5019b5
+	struct path_cxt *pc;
5019b5
+
5019b5
+	if (!ctl->require_handler)
5019b5
+		return 1;
5019b5
+
5019b5
+	pc = ul_new_procfs_path(ctl->pid, NULL);
5019b5
+	if (!pc)
5019b5
+		return -ENOMEM;
5019b5
+
5019b5
+	rc = procfs_process_get_stat_nth(pc, 34, &sigcgt);
5019b5
+	if (rc)
5019b5
+		return -EINVAL;
5019b5
+
5019b5
+	ul_unref_path(pc);
5019b5
+
5019b5
+	has_hnd = ((1UL << (ctl->numsig - 1)) & sigcgt) != 0;
5019b5
+	if (ctl->verbose && !has_hnd)
5019b5
+		printf(_("not signalling pid %d, it has no userspace handler for signal %d\n"), ctl->pid, ctl->numsig);
5019b5
+
5019b5
+	return has_hnd;
5019b5
+}
5019b5
+
5019b5
 int main(int argc, char **argv)
5019b5
 {
5019b5
 	struct kill_control ctl = { .numsig = SIGTERM };
5019b5
@@ -354,6 +386,8 @@
5019b5
 		errno = 0;
5019b5
 		ctl.pid = strtol(ctl.arg, &ep, 10);
5019b5
 		if (errno == 0 && ep && *ep == '\0' && ctl.arg < ep) {
5019b5
+			if (check_signal_handler(&ctl) <= 0)
5019b5
+				continue;
5019b5
 			if (kill_verbose(&ctl) != 0)
5019b5
 				nerrs++;
5019b5
 			ct++;
5019b5
@@ -368,6 +402,8 @@
5019b5
 
5019b5
 			proc_processes_filter_by_name(ps, ctl.arg);
5019b5
 			while (proc_next_pid(ps, &ctl.pid) == 0) {
5019b5
+				if (check_signal_handler(&ctl) <= 0)
5019b5
+					continue;
5019b5
 				if (kill_verbose(&ctl) != 0)
5019b5
 					nerrs++;
5019b5
 				ct++;