From f9366a82a3014027bd834fbf44c9e3fe012e5624 Mon Sep 17 00:00:00 2001 From: Simon Schubert Date: Mon, 12 Mar 2007 21:07:42 +0000 Subject: [PATCH] 1:1 Userland threading stage 4.8/4: Add syscalls lwp_gettid() and lwp_kill(). --- include/signal.h | 3 +- include/unistd.h | 3 +- lib/libc/sys/Makefile.inc | 3 +- lib/libc/sys/lwp_gettid.2 | 64 ++++++++++++++++++++ lib/libc/sys/lwp_kill.2 | 93 ++++++++++++++++++++++++++++++ sys/emulation/43bsd/43bsd_signal.c | 4 +- sys/emulation/linux/linux_signal.c | 4 +- sys/kern/kern_prot.c | 12 +++- sys/kern/kern_sig.c | 46 +++++++++++++-- sys/kern/syscalls.master | 4 +- sys/sys/kern_syscall.h | 4 +- 11 files changed, 225 insertions(+), 15 deletions(-) create mode 100644 lib/libc/sys/lwp_gettid.2 create mode 100644 lib/libc/sys/lwp_kill.2 diff --git a/include/signal.h b/include/signal.h index 9417750f86..4a06482c34 100644 --- a/include/signal.h +++ b/include/signal.h @@ -33,7 +33,7 @@ * @(#)signal.h 8.3 (Berkeley) 3/30/94 * * $FreeBSD: src/include/signal.h,v 1.14 1999/10/02 19:33:23 marcel Exp $ - * $DragonFly: src/include/signal.h,v 1.4 2003/11/14 01:01:43 dillon Exp $ + * $DragonFly: src/include/signal.h,v 1.5 2007/03/12 21:07:41 corecode Exp $ */ #ifndef _SIGNAL_H_ @@ -80,6 +80,7 @@ __END_DECLS #endif #ifndef _POSIX_SOURCE int killpg (__pid_t, int); +int lwp_kill (__pid_t, lwpid_t, int); int sigaltstack (const stack_t *, stack_t *); int sigblock (int); int siginterrupt (int, int); diff --git a/include/unistd.h b/include/unistd.h index dfbe3bbb39..d238c2b57a 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -32,7 +32,7 @@ * * @(#)unistd.h 8.12 (Berkeley) 4/27/95 * $FreeBSD: src/include/unistd.h,v 1.35.2.10 2002/04/15 12:52:28 nectar Exp $ - * $DragonFly: src/include/unistd.h,v 1.20 2007/03/12 21:06:00 corecode Exp $ + * $DragonFly: src/include/unistd.h,v 1.21 2007/03/12 21:07:41 corecode Exp $ */ #ifndef _UNISTD_H_ @@ -159,6 +159,7 @@ int issetugid(void); int lchown(const char *, uid_t, gid_t); int lockf(int, int, off_t); int lwp_create(struct lwp_params *); +lwpid_t lwp_gettid(void); char *mkdtemp(char *); int mknod(const char *, mode_t, dev_t); int mkstemp(char *); diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index 0615274965..23dcb2eeba 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -1,6 +1,6 @@ # @(#)Makefile.inc 8.3 (Berkeley) 10/24/94 # $FreeBSD: src/lib/libc/sys/Makefile.inc,v 1.75.2.7 2003/04/22 17:31:18 trhodes Exp $ -# $DragonFly: src/lib/libc/sys/Makefile.inc,v 1.23 2007/02/25 14:07:13 corecode Exp $ +# $DragonFly: src/lib/libc/sys/Makefile.inc,v 1.24 2007/03/12 21:07:42 corecode Exp $ # sys sources .PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/sys ${.CURDIR}/../libc/sys @@ -77,6 +77,7 @@ MAN+= _exit.2 accept.2 access.2 acct.2 adjtime.2 \ intro.2 ioctl.2 issetugid.2 jail.2 jail_attach.2 kill.2 \ kldfind.2 kldfirstmod.2 kldload.2 kldnext.2 kldstat.2 kldsym.2 \ kldunload.2 ktrace.2 kqueue.2 link.2 listen.2 lseek.2 \ + lwp_create.2 lwp_gettid.2 lwp_kill.2 \ madvise.2 mincore.2 minherit.2 mkdir.2 mkfifo.2 mknod.2 mlock.2 mmap.2 \ modfind.2 modnext.2 modstat.2 \ mount.2 mprotect.2 msync.2 munmap.2 nanosleep.2 \ diff --git a/lib/libc/sys/lwp_gettid.2 b/lib/libc/sys/lwp_gettid.2 new file mode 100644 index 0000000000..b39ddb171c --- /dev/null +++ b/lib/libc/sys/lwp_gettid.2 @@ -0,0 +1,64 @@ +.\" Copyright (c) 2007 The DragonFly Project. All rights reserved. +.\" +.\" This code is derived from software contributed to The DragonFly Project +.\" by Simon 'corecode' Schubert +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" 3. Neither the name of The DragonFly Project nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific, prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, +.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $DragonFly: src/lib/libc/sys/lwp_gettid.2,v 1.1 2007/03/12 21:07:42 corecode Exp $ +.\" +.Dd March 12, 2007 +.Dt LWP_GETTID 2 +.Os +.Sh NAME +.Nm lwp_gettid +.Nd get calling lwp identification +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft lwpid_t +.Fn lwp_gettid "void" +.Sh DESCRIPTION +The +.Fn lwp_gettid +function returns the lwp id of the calling lwp. +.Sh ERRORS +The +.Fn lwp_gettid +function is always successful and no return value is reserved +to indicate an error. +.Sh SEE ALSO +.Xr getpid 2 , +.Xr getppid 2 , +.Xr lwp_create 2 +.Sh HISTORY +The +.Fn lwp_gettid +function first appeared in +.Dx 1.9 . diff --git a/lib/libc/sys/lwp_kill.2 b/lib/libc/sys/lwp_kill.2 new file mode 100644 index 0000000000..353d00a306 --- /dev/null +++ b/lib/libc/sys/lwp_kill.2 @@ -0,0 +1,93 @@ +.\" Copyright (c) 2007 The DragonFly Project. All rights reserved. +.\" +.\" This code is derived from software contributed to The DragonFly Project +.\" by Simon 'corecode' Schubert +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" 3. Neither the name of The DragonFly Project nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific, prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, +.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $DragonFly: src/lib/libc/sys/lwp_kill.2,v 1.1 2007/03/12 21:07:42 corecode Exp $ +.\" +.Dd March 12, 2007 +.Dt LWP_KILL 2 +.Os +.Sh NAME +.Nm lwp_kill +.Nd send signal to a lwp +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In signal.h +.Ft int +.Fn lwp_kill "pid_t pid" "lwpid_t tid" "int sig" +.Sh DESCRIPTION +The +.Fn lwp_kill +function is used to send the signal +.Fa sig +to the lwp specified by +.Fa pid +and +.Fa tid . +If +.Fa pid +is set to -1, the current process will be used. +Permission checking and signal behavior is exactly like it is in +.Xr kill 2 . +.Sh RETURN VALUES +The +.Fn lwp_kill +function returns the value 0 if successful; +otherwise the value -1 is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +.Fn Lwp_kill +will fail and no signal will be sent if: +.Bl -tag -width Er +.It Bq Er EINVAL +.Fa Sig +is not a valid signal number. +.It Bq Er ESRCH +No lwp can be found corresponding to that specified by +.Fa pid +and +.Fa tid . +.It Bq Er EPERM +The sending process is not the super-user and its effective +user id does not match the effective user-id of the receiving process. +.El +.Sh SEE ALSO +.Xr kill 2 , +.Xr lwp_create 2 , +.Xr raise 3 , +.Sh HISTORY +The +.Fn lwp_kill +function first appeared in +.Dx 1.9 . diff --git a/sys/emulation/43bsd/43bsd_signal.c b/sys/emulation/43bsd/43bsd_signal.c index 2635198588..865040069b 100644 --- a/sys/emulation/43bsd/43bsd_signal.c +++ b/sys/emulation/43bsd/43bsd_signal.c @@ -37,7 +37,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/emulation/43bsd/43bsd_signal.c,v 1.4 2007/02/03 17:05:57 corecode Exp $ + * $DragonFly: src/sys/emulation/43bsd/43bsd_signal.c,v 1.5 2007/03/12 21:07:42 corecode Exp $ * from: DragonFly kern/kern_sig.c,v 1.22 * * These syscalls used to live in kern/kern_sig.c. They are modified @@ -166,7 +166,7 @@ sys_okillpg(struct okillpg_args *uap) { int error; - error = kern_kill(uap->signum, -uap->pgid); + error = kern_kill(uap->signum, -uap->pgid, -1); return (error); } diff --git a/sys/emulation/linux/linux_signal.c b/sys/emulation/linux/linux_signal.c index 834a258061..ebcf6a4d45 100644 --- a/sys/emulation/linux/linux_signal.c +++ b/sys/emulation/linux/linux_signal.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/compat/linux/linux_signal.c,v 1.23.2.3 2001/11/05 19:08:23 marcel Exp $ - * $DragonFly: src/sys/emulation/linux/linux_signal.c,v 1.13 2007/02/03 17:05:57 corecode Exp $ + * $DragonFly: src/sys/emulation/linux/linux_signal.c,v 1.14 2007/03/12 21:07:42 corecode Exp $ */ #include @@ -361,7 +361,7 @@ sys_linux_kill(struct linux_kill_args *args) else sig = args->signum; - error = kern_kill(sig, args->pid); + error = kern_kill(sig, args->pid, -1); return(error); } diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 93963205e7..996943c2e5 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -37,7 +37,7 @@ * * @(#)kern_prot.c 8.6 (Berkeley) 1/21/94 * $FreeBSD: src/sys/kern/kern_prot.c,v 1.53.2.9 2002/03/09 05:20:26 dd Exp $ - * $DragonFly: src/sys/kern/kern_prot.c,v 1.27 2007/01/08 21:32:57 corecode Exp $ + * $DragonFly: src/sys/kern/kern_prot.c,v 1.28 2007/03/12 21:07:42 corecode Exp $ */ /* @@ -91,6 +91,16 @@ sys_getppid(struct getppid_args *uap) return (0); } +/* ARGSUSED */ +int +sys_lwp_gettid(struct lwp_gettid_args *uap) +{ + struct lwp *lp = curthread->td_lwp; + + uap->sysmsg_result = lp->lwp_tid; + return (0); +} + /* * Get process group ID; note that POSIX getpgrp takes no parameter * diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index c1501666a5..71b24ad8e3 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -37,7 +37,7 @@ * * @(#)kern_sig.c 8.7 (Berkeley) 4/18/94 * $FreeBSD: src/sys/kern/kern_sig.c,v 1.72.2.17 2003/05/16 16:34:34 obrien Exp $ - * $DragonFly: src/sys/kern/kern_sig.c,v 1.74 2007/02/26 03:55:22 corecode Exp $ + * $DragonFly: src/sys/kern/kern_sig.c,v 1.75 2007/03/12 21:07:42 corecode Exp $ */ #include "opt_ktrace.h" @@ -694,10 +694,11 @@ killpg_all_callback(struct proc *p, void *data) } int -kern_kill(int sig, int pid) +kern_kill(int sig, pid_t pid, lwpid_t tid) { struct thread *td = curthread; struct proc *p = td->td_proc; + struct lwp *lp = NULL; if ((u_int)sig > _SIG_MAXSIG) return (EINVAL); @@ -707,10 +708,24 @@ kern_kill(int sig, int pid) return (ESRCH); if (!CANSIGNAL(p, sig)) return (EPERM); + if (tid != -1) { + FOREACH_LWP_IN_PROC(lp, p) { + if (lp->lwp_tid == tid) + break; + } + if (lp == NULL) + return (ESRCH); + } if (sig) - ksignal(p, sig); + lwpsignal(p, lp, sig); return (0); } + /* + * If we come here, pid is a special broadcast pid. + * This doesn't mix with a tid. + */ + if (tid != -1) + return (EINVAL); switch (pid) { case -1: /* broadcast signal */ return (dokillpg(sig, 0, 1)); @@ -727,8 +742,31 @@ sys_kill(struct kill_args *uap) { int error; - error = kern_kill(uap->signum, uap->pid); + error = kern_kill(uap->signum, uap->pid, -1); + return (error); +} + +int +sys_lwp_kill(struct lwp_kill_args *uap) +{ + int error; + pid_t pid = uap->pid; + + /* + * A tid is mandatory for lwp_kill(), otherwise + * you could simply use kill(). + */ + if (uap->tid == -1) + return (EINVAL); + + /* + * To save on a getpid() function call for intra-process + * signals, pid == -1 means current process. + */ + if (pid == -1) + pid = curproc->p_pid; + error = kern_kill(uap->signum, pid, uap->tid); return (error); } diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 4eed477a2a..6869ba1024 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ - $DragonFly: src/sys/kern/syscalls.master,v 1.50 2007/03/01 01:46:52 corecode Exp $ + $DragonFly: src/sys/kern/syscalls.master,v 1.51 2007/03/12 21:07:42 corecode Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 ; $FreeBSD: src/sys/kern/syscalls.master,v 1.72.2.10 2002/07/12 08:22:46 alfred Exp $ @@ -678,3 +678,5 @@ size_t nbyte, int flags, off_t offset); } 494 STD BSD { void extexit(int how, int status, void *addr); } 495 STD BSD { int lwp_create(struct lwp_params *params); } +496 STD BSD { lwpid_t lwp_gettid(void); } +497 STD BSD { int lwp_kill(pid_t pid, lwpid_t tid, int signum); } diff --git a/sys/sys/kern_syscall.h b/sys/sys/kern_syscall.h index 882f2d2d23..85d621916c 100644 --- a/sys/sys/kern_syscall.h +++ b/sys/sys/kern_syscall.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/kern_syscall.h,v 1.34 2006/10/27 04:56:33 dillon Exp $ + * $DragonFly: src/sys/sys/kern_syscall.h,v 1.35 2007/03/12 21:07:42 corecode Exp $ */ #ifndef _SYS_KERN_SYSCALL_H_ @@ -90,7 +90,7 @@ int kern_sigprocmask(int how, struct __sigset *set, struct __sigset *oset); int kern_sigpending(struct __sigset *set); int kern_sigsuspend(struct __sigset *mask); int kern_sigaltstack(struct sigaltstack *ss, struct sigaltstack *oss); -int kern_kill(int sig, int id); +int kern_kill(int sig, pid_t pid, lwpid_t tid); /* * Prototypes for syscalls in kern/sys_generic.c -- 2.41.0