zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: add -q option to kill for sigqueue
@ 2023-11-24 23:46 Oliver Kiddle
  2023-12-04 21:58 ` Oliver Kiddle
  2023-12-05  2:25 ` Bart Schaefer
  0 siblings, 2 replies; 3+ messages in thread
From: Oliver Kiddle @ 2023-11-24 23:46 UTC (permalink / raw)
  To: Zsh workers

The following adds support for a -q option to kill which takes a numeric
argument. It then uses sigqueue(2) to send the signal with the provided
number which a signal handler can pick up as si_value.sival_int in the
siginfo_t parameter. The util-linux kill also supports a similar option.
sigqueue and a range of "realtime" signals are specified in POSIX and
well supported. As far as I can tell, the RT signals are intended for
user-defined purposes like SIGUSR1 and USR2. The value can be an int or
a pointer but in practice, sending a pointer is fairly useless given
that signals are usually sent to a different process.

We could potentially make the signal value and other details such as
si_pid available to trap handlers. Perhaps using namespaced variables -
e.g. .signal.pid and .signal.value? However, I don't really understand
enough about how trap is implemented to know how (or whether) that can
be done safely.

It also ought to be possible to make SIGRTMIN through to SIGRTMAX
available. util-linux's kill allows those to be specified as RT<n>,
RTMIN+<n> or RTMAX-<n>. Would that need us to muck around with
signames2.awk or is leaving them out of $signals / kill -l and using
#ifdef RTMIN sufficient?

Oliver

diff --git a/Src/jobs.c b/Src/jobs.c
index a3b9f667a..4e9767ee4 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -2677,9 +2677,35 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
 {
     int sig = SIGTERM;
     int returnval = 0;
+#ifdef HAVE_SIGQUEUE
+    union sigval sigqueue_info;
+#endif
+    int use_sigqueue = 0, got_sig = 0;
+
+    while (*argv && **argv == '-') {
+	if (!use_sigqueue && (*argv)[1] == 'q' && (*argv)[2] == '\0') {
+	    char *endp;
+
+	    if (!*++argv) {
+		zwarnnam(nam, "-q: argument expected");
+		return 1;
+	    }
+#ifdef HAVE_SIGQUEUE
+	    sigqueue_info.sival_int =
+#endif
+		    zstrtol(*argv, &endp, 10);
+	    if (*endp) {
+		zwarnnam(nam, "invalid number: %s", *argv);
+		return 1;
+	    }
+	    use_sigqueue = 1;
+	    argv++;
+	    continue;
+	}
+	if (got_sig)
+	    break;
 
     /* check for, and interpret, a signal specifier */
-    if (*argv && **argv == '-') {
 	if (idigit((*argv)[1])) {
 	    char *endp;
 	    /* signal specified by number */
@@ -2796,6 +2822,7 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
 	    }
 	}
 	argv++;
+	got_sig = 1;
     }
 
     /* Discard the standard "-" and "--" option breaks */
@@ -2844,7 +2871,12 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
 	    returnval++;
 	} else {
 	    int pid = atoi(*argv);
-	    if (kill(pid, sig) == -1) {
+	    if (
+#ifdef HAVE_SIGQUEUE
+		use_sigqueue ? sigqueue(pid, sig, sigqueue_info) :
+#endif
+		kill(pid, sig) == -1)
+	    {
 		zwarnnam("kill", "kill %s failed: %e", *argv, errno);
 		returnval++;
 	    } 
diff --git a/configure.ac b/configure.ac
index c5263035e..9cb6e032b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1299,6 +1299,7 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \
 	       mkfifo _mktemp mkstemp \
 	       waitpid wait3 \
 	       sigaction sigblock sighold sigrelse sigsetmask sigprocmask \
+	       sigqueue \
 	       killpg setpgid setpgrp tcsetpgrp tcgetattr nice \
 	       gethostname gethostbyname2 getipnodebyname \
 	       inet_aton inet_pton inet_ntop \


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-12-05  2:26 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-24 23:46 PATCH: add -q option to kill for sigqueue Oliver Kiddle
2023-12-04 21:58 ` Oliver Kiddle
2023-12-05  2:25 ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).