diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2024-04-19 14:29:05 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2024-04-23 16:51:09 +0000 |
commit | 53186bc1435e2c3ccf9c2124c066a08c6a80c504 (patch) | |
tree | b67b72228e2ca43713052240d273bb9c4077869c | |
parent | 0c11c1792b139baffbf74e5f1c6fe065708301cc (diff) | |
download | src-53186bc1435e2c3ccf9c2124c066a08c6a80c504.tar.gz src-53186bc1435e2c3ccf9c2124c066a08c6a80c504.zip |
sigqueue(2): add impl-specific flag __SIGQUEUE_TID
The flag allows the pid argument to designate a thread from the calling
process. The flag value is carved from the high bit of the signal
number, which slightly changes the ABI of syscall.
Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D44867
-rw-r--r-- | sys/kern/kern_sig.c | 22 | ||||
-rw-r--r-- | sys/sys/signal.h | 4 |
2 files changed, 21 insertions, 5 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index a533460090eb..7ac9dcb8cb40 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -2012,13 +2012,16 @@ sys_sigqueue(struct thread *td, struct sigqueue_args *uap) } int -kern_sigqueue(struct thread *td, pid_t pid, int signum, union sigval *value) +kern_sigqueue(struct thread *td, pid_t pid, int signumf, union sigval *value) { ksiginfo_t ksi; struct proc *p; + struct thread *td2; + u_int signum; int error; - if ((u_int)signum > _SIG_MAXSIG) + signum = signumf & ~__SIGQUEUE_TID; + if (signum > _SIG_MAXSIG) return (EINVAL); /* @@ -2028,8 +2031,17 @@ kern_sigqueue(struct thread *td, pid_t pid, int signum, union sigval *value) if (pid <= 0) return (EINVAL); - if ((p = pfind_any(pid)) == NULL) - return (ESRCH); + if ((signumf & __SIGQUEUE_TID) == 0) { + if ((p = pfind_any(pid)) == NULL) + return (ESRCH); + td2 = NULL; + } else { + p = td->td_proc; + td2 = tdfind((lwpid_t)pid, p->p_pid); + if (td2 == NULL) + return (ESRCH); + } + error = p_cansignal(td, p, signum); if (error == 0 && signum != 0) { ksiginfo_init(&ksi); @@ -2039,7 +2051,7 @@ kern_sigqueue(struct thread *td, pid_t pid, int signum, union sigval *value) ksi.ksi_pid = td->td_proc->p_pid; ksi.ksi_uid = td->td_ucred->cr_ruid; ksi.ksi_value = *value; - error = pksignal(p, ksi.ksi_signo, &ksi); + error = tdsendsignal(p, td2, ksi.ksi_signo, &ksi); } PROC_UNLOCK(p); return (error); diff --git a/sys/sys/signal.h b/sys/sys/signal.h index 068a7e7bc6da..690cab414e9e 100644 --- a/sys/sys/signal.h +++ b/sys/sys/signal.h @@ -475,6 +475,10 @@ struct sigstack { #if __BSD_VISIBLE #define BADSIG SIG_ERR + +/* sigqueue(2) signo high-bits flags */ +#define __SIGQUEUE_TID 0x80000000 /* queue for tid, instead of pid */ +#define __SIGQUEUE_RSRV 0x40000000 /* reserved */ #endif #if __POSIX_VISIBLE || __XSI_VISIBLE |