Index: lib/libc/sys/Makefile.inc =================================================================== --- lib/libc/sys/Makefile.inc (revision 253336) +++ lib/libc/sys/Makefile.inc (working copy) @@ -114,7 +114,8 @@ setgroups.2 setpgid.2 setregid.2 setresuid.2 setreuid.2 setsid.2 \ setuid.2 shmat.2 shmctl.2 shmget.2 shm_open.2 shutdown.2 \ sigaction.2 sigaltstack.2 sigpending.2 sigprocmask.2 sigqueue.2 \ - sigreturn.2 sigstack.2 sigsuspend.2 sigwait.2 sigwaitinfo.2 \ + sigreturn.2 sigsendset.2 sigstack.2 sigsuspend.2 \ + sigwait.2 sigwaitinfo.2 \ socket.2 socketpair.2 stat.2 statfs.2 \ swapon.2 symlink.2 sync.2 sysarch.2 syscall.2 \ timer_create.2 timer_delete.2 timer_settime.2 \ @@ -132,7 +133,7 @@ MLINKS+=clock_gettime.2 clock_getres.2 clock_gettime.2 clock_settime.2 MLINKS+=cpuset.2 cpuset_getid.2 cpuset.2 cpuset_setid.2 MLINKS+=cpuset_getaffinity.2 cpuset_setaffinity.2 -MLINKS+=dup.2 dup2.2 +MLINKS+=dup.2 dup2.2 dup.2 dup3.2 MLINKS+=execve.2 fexecve.2 MLINKS+=extattr_get_file.2 extattr.2 \ extattr_get_file.2 extattr_delete_fd.2 \ @@ -204,6 +205,7 @@ MLINKS+=setuid.2 setegid.2 setuid.2 seteuid.2 setuid.2 setgid.2 MLINKS+=shmat.2 shmdt.2 MLINKS+=shm_open.2 shm_unlink.2 +MLINKS+=sigsendset.2 sigsend.2 MLINKS+=sigwaitinfo.2 sigtimedwait.2 MLINKS+=stat.2 fstat.2 stat.2 fstatat.2 stat.2 lstat.2 MLINKS+=statfs.2 fstatfs.2 Index: lib/libc/gen/Symbol.map =================================================================== --- lib/libc/gen/Symbol.map (revision 253336) +++ lib/libc/gen/Symbol.map (working copy) @@ -382,11 +382,12 @@ FBSD_1.3 { fdlopen; __FreeBSD_libc_enter_restricted_mode; getcontextx; gid_from_group; nvis; pwcache_userdb; pwcache_groupdb; + sigsend; snvis; strenvisx; strnunvis; Index: lib/libc/gen/Makefile.inc =================================================================== --- lib/libc/gen/Makefile.inc (revision 253336) +++ lib/libc/gen/Makefile.inc (working copy) @@ -29,7 +29,8 @@ scandir.c seed48.c seekdir.c semctl.c \ setdomainname.c sethostname.c setjmperr.c setmode.c \ setproctitle.c setprogname.c siginterrupt.c siglist.c signal.c \ - sigsetops.c sleep.c srand48.c statvfs.c stringlist.c strtofflags.c \ + sigsend.c sigsetops.c sleep.c \ + srand48.c statvfs.c stringlist.c strtofflags.c \ sysconf.c sysctl.c sysctlbyname.c sysctlnametomib.c \ syslog.c telldir.c termios.c time.c times.c timezone.c tls.c \ ttyname.c ttyslot.c ualarm.c ulimit.c uname.c unvis-compat.c \ Index: lib/libc/include/namespace.h =================================================================== --- lib/libc/include/namespace.h (revision 253336) +++ lib/libc/include/namespace.h (working copy) @@ -224,6 +224,7 @@ #define setsockopt _setsockopt /*#define sigaction _sigaction*/ #define sigprocmask _sigprocmask +#define sigsendset _sigsendset #define sigsuspend _sigsuspend #define socket _socket #define socketpair _socketpair Index: lib/libc/include/un-namespace.h =================================================================== --- lib/libc/include/un-namespace.h (revision 253336) +++ lib/libc/include/un-namespace.h (working copy) @@ -205,6 +205,7 @@ #undef setsockopt #undef sigaction #undef sigprocmask +#undef sigsendset #undef sigsuspend #undef socket #undef socketpair Index: sys/bsm/audit_kevents.h =================================================================== --- sys/bsm/audit_kevents.h (revision 253336) +++ sys/bsm/audit_kevents.h (working copy) @@ -603,6 +603,7 @@ #define AUE_PDGETPID 43199 /* FreeBSD. */ #define AUE_PDWAIT 43200 /* FreeBSD. */ #define AUE_WAIT6 43201 /* FreeBSD. */ +#define AUE_SIGSENDSET 43202 /* FreeBSD. */ /* * Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the Index: sys/kern/makesyscalls.sh =================================================================== --- sys/kern/makesyscalls.sh (revision 253336) +++ sys/kern/makesyscalls.sh (working copy) @@ -153,6 +153,7 @@ printf "#include \n" > sysarg printf "#include \n" > sysarg printf "#include \n" > sysarg + printf "#include \n" > sysarg printf "#include \n\n" > sysarg printf "#include \n\n" > sysarg printf "struct proc;\n\n" > sysarg Index: sys/kern/syscalls.master =================================================================== --- sys/kern/syscalls.master (revision 253336) +++ sys/kern/syscalls.master (working copy) @@ -952,5 +952,7 @@ int *status, int options, \ struct __wrusage *wrusage, \ siginfo_t *info); } +533 AUE_SIGSENDSET STD { int sigsendset(procset_t *psp, int sig); } + ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master Index: sys/sys/syscallsubr.h =================================================================== --- sys/sys/syscallsubr.h (revision 253336) +++ sys/sys/syscallsubr.h (working copy) @@ -55,6 +55,7 @@ struct stat; struct thr_param; struct __wrusage; +struct __procset; int kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg, u_int buflen); @@ -206,6 +207,7 @@ int kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss); int kern_sigprocmask(struct thread *td, int how, sigset_t *set, sigset_t *oset, int flags); +int kern_sigsendset (struct thread *td, struct __procset *ps, int sign); int kern_sigsuspend(struct thread *td, sigset_t mask); int kern_sigtimedwait(struct thread *td, sigset_t waitset, struct ksiginfo *ksi, struct timespec *timeout); Index: sys/compat/freebsd32/syscalls.master =================================================================== --- sys/compat/freebsd32/syscalls.master (revision 253336) +++ sys/compat/freebsd32/syscalls.master (working copy) @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -1019,3 +1020,5 @@ struct wrusage32 *wrusage, \ siginfo_t *info); } #endif +533 AUE_SIGSENDSET STD { int freebsd32_sigsendset(struct procset32 *psp, \ + int sig); } Index: include/signal.h =================================================================== --- include/signal.h (revision 253336) +++ include/signal.h (working copy) @@ -120,6 +120,14 @@ int sigstack(const struct sigstack *, struct sigstack *); int sigvec(int, struct sigvec *, struct sigvec *); #endif + +#if __BSD_VISIBLE +#include + +int sigsend(idtype_t idtype, id_t id, int sig); +int sigsendset(procset_t *psetptr, int sig); +#endif + __END_DECLS #endif /* !_SIGNAL_H_ */ Index: sys/sys/wait.h =================================================================== --- sys/sys/wait.h (revision 253336) +++ sys/sys/wait.h (working copy) @@ -88,46 +88,8 @@ #define WLINUXCLONE 0x80000000 /* Wait for kthread spawned from linux_clone. */ #endif -#ifndef _IDTYPE_T_DECLARED -typedef enum -#if __BSD_VISIBLE - idtype /* pollutes XPG4.2 namespace */ -#endif - { - /* - * These names were mostly lifted from Solaris source code and - * still use Solaris style naming to avoid breaking any - * OpenSolaris code which has been ported to FreeBSD. There - * is no clear FreeBSD counterpart for all of the names, but - * some have a clear correspondence to FreeBSD entities. - * - * The numerical values are kept synchronized with the Solaris - * values. - */ - P_PID, /* A process identifier. */ - P_PPID, /* A parent process identifier. */ - P_PGID, /* A process group identifier. */ - P_SID, /* A session identifier. */ - P_CID, /* A scheduling class identifier. */ - P_UID, /* A user identifier. */ - P_GID, /* A group identifier. */ - P_ALL, /* All processes. */ - P_LWPID, /* An LWP identifier. */ - P_TASKID, /* A task identifier. */ - P_PROJID, /* A project identifier. */ - P_POOLID, /* A pool identifier. */ - P_JAILID, /* A zone identifier. */ - P_CTID, /* A (process) contract identifier. */ - P_CPUID, /* CPU identifier. */ - P_PSETID /* Processor set identifier. */ -} idtype_t; /* The type of id_t we are using. */ +#include -#if __BSD_VISIBLE -#define P_ZONEID P_JAILID -#endif -#define _IDTYPE_T_DECLARED -#endif - /* * Tokens for special values of the "pid" parameter to wait4. * Extended struct __wrusage to collect rusage for both the target Index: sys/kern/kern_sig.c =================================================================== --- sys/kern/kern_sig.c (revision 253336) +++ sys/kern/kern_sig.c (working copy) @@ -1714,7 +1714,281 @@ /* NOTREACHED */ } +/* + * This shall be called only while holding both + * PROC_LOCK(me) and PROC_LOCK(p). + */ +static int +pr_matches_id (me, p, idtype, id) + struct proc *me; + struct proc *p; + idtype_t idtype; + id_t id; +{ + int ret = 0; /* Assume no match. */ + + switch (idtype) { + case P_ALL: + ret = 1; + break; + case P_PID: + if (id == P_MYID) + id = (id_t)me->p_pid; + ret = (p->p_pid == (pid_t)id) ? 1 : 0; + break; + case P_PGID: + if (id == P_MYID) + id = (id_t)me->p_pgid; + ret = (p->p_pgid == (pid_t)id) ? 1 : 0; + break; + case P_SID: + if (id == P_MYID) + id = (id_t)me->p_session->s_sid; + ret = (p->p_session->s_sid == (pid_t)id) ? 1 : 0; + break; + case P_UID: + if (id == P_MYID) + id = (id_t)me->p_ucred->cr_uid; + ret = (p->p_ucred->cr_uid == (uid_t)id) ? 1 : 0; + break; + case P_GID: + if (id == P_MYID) + id = (id_t)me->p_ucred->cr_gid; + ret = (p->p_ucred->cr_gid == (gid_t)id) ? 1 : 0; + break; + case P_JAILID: + if (p->p_ucred->cr_prison == NULL) + return (0); + if (id == P_MYID) { + if (me->p_ucred->cr_prison == NULL) + return (0); + id = (id_t) me->p_ucred->cr_prison->pr_id; + } + ret = (p->p_ucred->cr_prison->pr_id == (int)id) ? 1 : 0; + break; + default: + /* + * Currently no support for + * P_CID, P_CPUID, P_PSETID, P_POOLID, + * P_LWPID, P_CTID, P_TASKID, P_PROJID, + * usw. + */ + return (0); + break; + } + return (ret); +} + +static int +supported_sigsend_idtype (idtype) + idtype_t idtype; +{ + switch (idtype) { + case P_ALL: + case P_PID: + case P_PGID: + case P_SID: + case P_UID: + case P_GID: + case P_JAILID: + return (1); + break; + default: + /* + * Currently no support for + * P_CID, P_CPUID, P_PSETID, P_POOLID, + * P_LWPID, P_CTID, P_TASKID, P_PROJID, + * usw. + */ + break; + } + return (0); +} + int +kern_sigsendset (td, ps, sig) + struct thread *td; + procset_t *ps; + int sig; +{ + ksiginfo_t ksi; + struct proc *p; + struct proc *me; + int error; + int ret; + int lmatch; + int rmatch; + + if ((u_int)sig > _SIG_MAXSIG) + return (EINVAL); + + AUDIT_ARG_SIGNUM(sig); + AUDIT_ARG_VALUE(ps->p_op); /* XXX These 5 may be wrong! */ + AUDIT_ARG_VALUE(ps->p_lidtype); + AUDIT_ARG_VALUE(ps->p_lid); + AUDIT_ARG_VALUE(ps->p_ridtype); + AUDIT_ARG_VALUE(ps->p_rid); + + if (!supported_sigsend_idtype(ps->p_lidtype) || + !supported_sigsend_idtype(ps->p_ridtype)) + return (EINVAL); + + switch (ps->p_op) { + case POP_AND: + case POP_DIFF: + case POP_OR: + case POP_XOR: + break; + default: + return (EINVAL); + break; + } + + ksiginfo_init(&ksi); + ksi.ksi_signo = sig; + ksi.ksi_code = SI_USER; + ksi.ksi_pid = td->td_proc->p_pid; + ksi.ksi_uid = td->td_ucred->cr_ruid; + + me = td->td_proc; + + ret = ESRCH; + sx_slock(&allproc_lock); + FOREACH_PROC_IN_SYSTEM(p) { + PROC_LOCK(p); + PROC_LOCK(me); + + /* + * Short circuit out all those processes which + * we do not wish to touch in any case. + * + * This is simply for readability. + * The compiler will certainly optimize these to + * one larger OR condition block with a single body. + */ + + if ((p->p_pid == 0) || + ((p->p_flag & P_SYSTEM) || (p->p_state == PRS_NEW))) { + PROC_UNLOCK(me); + PROC_UNLOCK(p); + continue; + } + else if ((ps->p_lidtype != P_PID) && + ((p == me) || (p->p_pid == 1))) { + PROC_UNLOCK(me); + PROC_UNLOCK(p); + continue; + } + else if ((ps->p_ridtype != P_PID) && + ((p == me) || (p->p_pid == 1))) { + PROC_UNLOCK(me); + PROC_UNLOCK(p); + continue; + } + + switch (ps->p_op) { + case POP_OR: + if (!pr_matches_id (me, p, + ps->p_lidtype, ps->p_lid) && + !pr_matches_id (me, p, + ps->p_ridtype, ps->p_rid)) { + PROC_UNLOCK(me); + PROC_UNLOCK(p); + continue; + } + break; + case POP_AND: + if (!pr_matches_id (me, p, + ps->p_lidtype, ps->p_lid) || + !pr_matches_id (me, p, + ps->p_ridtype, ps->p_rid)) { + PROC_UNLOCK(me); + PROC_UNLOCK(p); + continue; + } + break; + case POP_DIFF: + if (!pr_matches_id (me, p, + ps->p_lidtype, ps->p_lid) || + pr_matches_id (me, p, + ps->p_ridtype, ps->p_rid)) { + PROC_UNLOCK(me); + PROC_UNLOCK(p); + continue; + } + break; + case POP_XOR: + lmatch = pr_matches_id (me, p, + ps->p_lidtype, ps->p_lid); + rmatch = pr_matches_id (me, p, + ps->p_ridtype, ps->p_rid); + /* + * NOTE! - The values are always either 0 or 1. + * So, we can use binary XOR here. + */ + if (! (lmatch ^ rmatch)) { + PROC_UNLOCK(me); + PROC_UNLOCK(p); + continue; + } + break; + default: + /* + * We should never get here! + */ + PROC_UNLOCK(me); + PROC_UNLOCK(p); + ret = EINVAL; + goto Cleanup; + break; + } + + PROC_UNLOCK(me); + + error = p_cansignal(td, p, sig); + if (error == 0) { + if (sig) + pksignal(p, sig, &ksi); + ret = 0; + } + else if (ret == ESRCH) + ret = error; + + PROC_UNLOCK(p); + } +Cleanup: + sx_sunlock(&allproc_lock); + return (ret); +} + +#ifndef _SYS_SYSPROTO_H_ +struct sigsendset_args { + procset_t *psp; + int sig; +}; +#endif +int +sys_sigsendset (td, uap) + struct thread *td; + struct sigsendset_args *uap; +{ + int error; + procset_t pset; + + if ((u_int)uap->sig > _SIG_MAXSIG) + return (EINVAL); + + if (uap->psp == NULL) + return (EFAULT); + + error = copyin(uap->psp, &pset, sizeof (pset)); + if (error != 0) + return (error); + + return (kern_sigsendset (td, &pset, uap->sig)); +} + +int sys_pdkill(td, uap) struct thread *td; struct pdkill_args *uap; Index: sys/compat/freebsd32/freebsd32.h =================================================================== --- sys/compat/freebsd32/freebsd32.h (revision 253515) +++ sys/compat/freebsd32/freebsd32.h (working copy) @@ -89,6 +89,16 @@ struct timeval32 it_value; }; +struct procset32 { + int32_t p_op; + int32_t p_lidtype; + int32_t p_lid1; + int32_t p_lid2; + int32_t p_ridtype; + int32_t p_rid1; + int32_t p_rid2; +}; + #define FREEBSD4_MNAMELEN (88 - 2 * sizeof(int32_t)) /* size of on/from name bufs */ /* 4.x version */ Index: sys/compat/freebsd32/freebsd32_misc.c =================================================================== --- sys/compat/freebsd32/freebsd32_misc.c (revision 253515) +++ sys/compat/freebsd32/freebsd32_misc.c (working copy) @@ -210,6 +210,31 @@ return (error); } +int +freebsd32_sigsendset (td, uap) + struct thread *td; + struct freebsd32_sigsendset_args *uap; +{ + int error; + procset_t pset; + struct procset32 pset32; + + if (uap->psp == NULL) + return (EFAULT); + + error = copyin(uap->psp, &pset32, sizeof (pset32)); + if (error != 0) + return (error); + + pset.p_op = pset32.p_op; + pset.p_lidtype = pset32.p_lidtype; + pset.p_lid = (id_t) PAIR32TO64 (int64_t, pset32.p_lid); + pset.p_ridtype = pset32.p_ridtype; + pset.p_rid = (id_t) PAIR32TO64 (int64_t, pset32.p_rid); + + return (kern_sigsendset (td, &pset, uap->sig)); +} + #ifdef COMPAT_FREEBSD4 static void copy_statfs(struct statfs *in, struct statfs32 *out) --- /dev/null 2013-07-14 20:33:01.319644342 +0300 +++ sys/sys/_idtype.h 2013-07-14 12:11:32.250746532 +0300 @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 2012-2013 Jukka A. Ukkonen + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD: stable/9/sys/sys/_idtype.h 244172 2012-12-13 06:17:05Z jau $ + */ + +#ifndef _SYS__IDTYPE_H_ +#define _SYS__IDTYPE_H_ + +#ifndef _IDTYPE_T_DECLARED +typedef enum +#if __BSD_VISIBLE + idtype /* pollutes XPG4.2 namespace */ +#endif + { + /* + * These names were mostly lifted from Solaris source code and + * still use Solaris style naming to avoid breaking any + * OpenSolaris code which has been ported to FreeBSD. There + * is no clear FreeBSD counterpart for all of the names, but + * some have a clear correspondence to FreeBSD entities. + * + * The numerical values are kept synchronized with the Solaris + * values. + */ + P_PID, /* A process identifier. */ + P_PPID, /* A parent process identifier. */ + P_PGID, /* A process group identifier. */ + P_SID, /* A session identifier. */ + P_CID, /* A scheduling class identifier. */ + P_UID, /* A user identifier. */ + P_GID, /* A group identifier. */ + P_ALL, /* All processes. */ + P_LWPID, /* An LWP identifier. */ + P_TASKID, /* A task identifier. */ + P_PROJID, /* A project identifier. */ + P_POOLID, /* A pool identifier. */ + P_JAILID, /* A zone identifier. */ + P_CTID, /* A (process) contract identifier. */ + P_CPUID, /* CPU identifier. */ + P_PSETID /* Processor set identifier. */ +} idtype_t; /* The type of id_t we are using. */ + +#if __BSD_VISIBLE +#define P_ZONEID P_JAILID +#endif +#define _IDTYPE_T_DECLARED +#endif + +#endif --- /dev/null 2013-07-14 20:36:10.172402008 +0300 +++ sys/sys/procset.h 2013-07-14 20:37:56.841311890 +0300 @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2012-2013 Jukka A. Ukkonen + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD: stable/9/sys/sys/procset.h 244172 2012-12-13 06:17:05Z jau $ + */ + +#ifndef _SYS_PROCSET_H_ +#define _SYS_PROCSET_H_ + +#include +#include + +typedef enum { + POP_OR, POP_AND, POP_XOR, POP_DIFF, +} idop_t; + +struct __procset { + idop_t p_op; + idtype_t p_lidtype; + id_t p_lid; + idtype_t p_ridtype; + id_t p_rid; +}; + +typedef struct __procset procset_t; + +/* + * Notice! + * The true process ID 0 would be anyhow excluded as a target. + */ + +#define P_MYID 0 + +#endif --- /dev/null 2013-07-17 12:22:00.310404771 +0300 +++ lib/libc/sys/sigsendset.2 2013-07-17 12:23:35.791016650 +0300 @@ -0,0 +1,381 @@ +.\" Copyright (c) 2012-2013 Jukka A. Ukkonen +.\" All rights reserved. +.\" +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +.\" +.\" $FreeBSD: stable/9/lib/libc/sys/sigsendset.2 241224 2012-10-05 14:20:53Z jau $ +.\" +.Dd July 14, 2013 +.Dt SIGSENDSET 2 +.Os +.Sh NAME +.Nm sigsend , +.Nm sigsendset +.Nd send a signal to a process or a group of processes +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In signal.h +.Bd -literal +struct __procset { + idop_t p_op; + idtype_t p_lidtype; + id_t p_lid; + idtype_t p_ridtype; + id_t p_rid; +}; + +typedef struct __procset procset_t; +.Ed +.Ft int +.Fo sigsend +.Fa "idtype_t idtype" +.Fa "id_t id" +.Fa "int sig" +.Fc +.Ft int +.Fo sigsendset +.Fa "procset_t *pset" +.Fa "int sig" +.Fc +.Sh DESCRIPTION +The +.Fn sigsend +function sends a signal to the process or group of processes specified +by +.Fa id +and +.Fa idtype . +The signal to be sent is specified by sig and is either 0 or one of +the values listed in +.In signal.h . +If +.Fa sig +is +.Dv 0 +(the null signal), error checking is performed but no signal is actually sent. +This value can be used to check the validity of +.Fa id +and +.Fa idtype . +.Pp +The real or effective user +.Nm ID +of the the sending process must match the real or saved user ID of + the receiving process, unless the sender is +.Nm root +or alternatively privileged through some privilege policy to send signals +to processes owned by other UIDs. +The signal can also be sent when +.Fa sig +is +.Dv SIGCONT +and the sending process has the same session ID as the receiving process. +.Pp +If +.Fa idtype +is +.Dv P_PID , +.Fa sig +is sent to the process with process +.Nm ID +.Fa id . +.Pp +If +.Fa idtype +is +.Dv P_PGID , +.Fa sig +is sent to all the processes with process groupd +.Nm ID +.Fa id . +.Pp +If +.Fa idtype +is +.Dv P_SID , +.Fa sig +is sent to all the processes with session +.Nm ID +.Fa id . +.\" // No task consept in FreeBSD yet. +.\" .Pp +.\" If +.\" .Fa idtype +.\" is +.\" .Dv P_TASKID , +.\" .Fa sig +.\" is sent to all the processes with task +.\" .Nm ID +.\" .Fa id . +.Pp +If +.Fa idtype +is +.Dv P_UID , +.Fa sig +is sent to all processes with effective user +.Nm ID +.Fa id . +.Pp +If +.Fa idtype +is +.Dv P_GID , +.Fa sig +is sent to all processes with effective group +.Nm ID +.Fa id . +.\" // No project consept in FreeBSD yet. +.\" .Pp +.\" If +.\" .Fa idtype +.\" is +.\" .Dv P_PROJID , +.\" .Fa sig +.\" is sent to all the processes with project +.\" .Nm ID +.\" .Fa id . +.\" // The CID a.k.a. the scheduling class would be otherwise easy +.\" // but at the moment all scheduling class info is in the thread +.\" // structures. +.\" // Thus the process has no unique or primary scheduling class +.\" // of its own. :( +.\" .Pp +.\" If +.\" .Fa idtype +.\" is +.\" .Dv P_CID , +.\" .Fa sig +.\" is sent to all the processes with scheduler class +.\" .Nm ID +.\" .Fa id . +.\" // No contract consept in FreeBSD yet. +.\" .Pp +.\" If +.\" .Fa idtype +.\" is +.\" .Dv P_CTID , +.\" .Fa sig +.\" is sent to all the processes with process contract +.\" .Nm ID +.\" .Fa id . +.Pp +If +.Fa idtype +is +.Dv P_JAILID , +.Fa sig +is sent to all processes running in jail +.Nm ID +.Fa id . +.Pp +If +.Fa idtype +is +.Dv P_ALL , +.Fa sig +is sent to all processes that fall within the sender's privileges +and +.Fa id +is ignored. +.Pp +If +.Fa id +is +.Dv P_MYID , +the value of +.Fa id +is taken from the current process. +.Pp +The process with a process +.Nm ID +of +.Dv 0 +always excluded. +The process with a process +.Nm ID +of +.Dv 1 +is excluded unless the +.Fa idtype +is equal to +.Dv P_PID . +.Pp +The +.Fn sigsendset +function provides an alternate interface for sending signals to sets of +processes. This function sends signals to the set of processes specified by +.Fa pset . +.Fa pset +is a pointer to a structure of type +.Nm procset_t , +defined in +.In sys/procset.h , +which includes the members shown in the +.Nm SYNOPSIS +section above. +.Pp +The +.Fa p_lidtype +and +.Fa p_lid +members specify the +.Nm ID +type and +.Nm ID +of the "left" set of processes; the +.Fa p_ridtype +and +.Fa p_rid +members specify the +.Nm ID +type and +.Nm ID +of the "right" set of processes. +ID types and IDs are specified just as for the +.Fa idtype +and +.Fa id +arguments to +.Fn sigsend . +The +.Fa p_op +member specifies the operation to be performed on the two sets of +processes to get the set of processes the function is to apply to. +The valid value for +.Fa p_op +and the processes they specify are: +.Bl -tag -width Nm +.It Nm POP_DIFF +Set difference: processes in left set and not in right set. +.It Nm POP_AND +Set intersection: processes in both left and right sets. +.It Nm POP_OR +Set union: processes in either left or right set or in both. +.It Nm POP_XOR +Set exclusive-or: processes in either left or right set but in both. +.El +.Sh RETURN VALUES +.Rv -std sigsend sigsendset +.Sh ERRORS +The +.Fn sigsend +and +.Fn sigsendset +functions will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa sig +argument is not a valid signal number, or the +.Fa idtype +argument is not a supported idtype. +.It Bq Er EINVAL +The +.Fa sig +argument is +.Dv SIGKILL , +.Fa idtype +is +.Dv P_PID +and +.Fa id +is +.Dv 1 . +.It Bq Er EPERM +The effective user of the calling process does not +match the real or saved user ID of the receiving +process, the calling process does not have sufficient +privileges \fI(root)\fP, and the calling process is +not sending +.Dv SIGCONT +to a process that shares the same session ID. +.sp +The calling process does not have sufficient privileges +\fI(root)\fP and is trying to send a signal to a process +with a different session ID, even though the effective +user ID of the sender matches the real or saved ID of +the receiving process. +.It Bq Er ESRCH +No process can be found corresponding to that specified by +.Fa idtype +and +.Fa id . +.El +.Pp +The +.Fn sigsendset +function will also fail if: +.Bl -tag -width Er +.It Bq Er EFAULT +The +.Fa pset +argument points to an illegal address. +.El +.Sh SEE ALSO +.Xr kill 1 , +.Xr kill 2 , +.Xr getpid 2 , +.Xr signal 2 , +.Xr sigaction 2 , +.Xr wait 2 +.Sh STANDARDS +The functions +.Fn sigsend +and +.Fn sigsendset +are not required by any standards. +They are compatibility functions only. +These functions have been previously present +in multiple commercial +.Ux +versions. +At least +.Nm SunOS/Solaris , +.Nm HP-UX , +.Nm IRIX , +and +.Nm Tru64 +are examples of vendors which have included +these functions in their standard libraries. +.Sh NOTE +Though these functions provide flexibility and convenience in sending +signals to a large number of processes in a single function call and +though they allow specifying target processes using also other ID types +than +.Dv P_PID , +.Dv P_PGID , +and +.Dv P_ALL +which are available through the traditional +.Fn kill , +using them in your code may limit portability +to operating systems which do not provide these +functions. \fI(e.g. Linux and AIX)\fP +.Sh AUTHOR +These APIs were implemented by Jukka A. Ukkonen, 2012-2013. +.sp +This manual page was converted to mdoc +by Jukka A. Ukkonen, 2013, +from its Solaris counterpart. +A few changes were introduced in the process. --- /dev/null 2013-07-17 19:55:01.240877948 +0300 +++ lib/libc/gen/sigsend.c 2013-07-17 19:56:30.403223006 +0300 @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2012-2013 Jukka A. Ukkonen + * All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD: stable/9/sys/sys/_idtype.h 244172 2012-12-13 06:17:05Z jau $ + */ + +#include "namespace.h" +#include +#include +#include "un-namespace.h" + +int +__sigsend (idtype, id, sig) + idtype_t idtype; + id_t id; + int sig; +{ + procset_t pset; + + pset.p_op = POP_OR; + pset.p_lidtype = pset.p_ridtype = idtype; + pset.p_lid = pset.p_rid = id; + + return (_sigsendset (&pset, sig)); +} + +__weak_reference(__sigsend, sigsend); +__weak_reference(__sigsend, _sigsend);