10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*2248Sraf * Common Development and Distribution License (the "License").
6*2248Sraf * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*2248Sraf
220Sstevel@tonic-gate /*
23*2248Sraf * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24*2248Sraf * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
27*2248Sraf /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
280Sstevel@tonic-gate
290Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
300Sstevel@tonic-gate
310Sstevel@tonic-gate #include <sys/param.h>
320Sstevel@tonic-gate #include <sys/types.h>
330Sstevel@tonic-gate #include <sys/sysmacros.h>
340Sstevel@tonic-gate #include <sys/systm.h>
350Sstevel@tonic-gate #include <sys/errno.h>
360Sstevel@tonic-gate #include <sys/proc.h>
370Sstevel@tonic-gate #include <sys/procset.h>
380Sstevel@tonic-gate #include <sys/fault.h>
390Sstevel@tonic-gate #include <sys/signal.h>
400Sstevel@tonic-gate #include <sys/siginfo.h>
410Sstevel@tonic-gate #include <sys/debug.h>
420Sstevel@tonic-gate
430Sstevel@tonic-gate static int
sigqkill(pid_t pid,sigsend_t * sigsend)44*2248Sraf sigqkill(pid_t pid, sigsend_t *sigsend)
450Sstevel@tonic-gate {
46*2248Sraf proc_t *p;
470Sstevel@tonic-gate int error;
480Sstevel@tonic-gate
49*2248Sraf if ((uint_t)sigsend->sig >= NSIG)
50*2248Sraf return (EINVAL);
510Sstevel@tonic-gate
520Sstevel@tonic-gate if (pid == -1) {
530Sstevel@tonic-gate procset_t set;
540Sstevel@tonic-gate
550Sstevel@tonic-gate setprocset(&set, POP_AND, P_ALL, P_MYID, P_ALL, P_MYID);
560Sstevel@tonic-gate error = sigsendset(&set, sigsend);
570Sstevel@tonic-gate } else if (pid > 0) {
580Sstevel@tonic-gate mutex_enter(&pidlock);
590Sstevel@tonic-gate if ((p = prfind(pid)) == NULL || p->p_stat == SIDL)
600Sstevel@tonic-gate error = ESRCH;
610Sstevel@tonic-gate else {
620Sstevel@tonic-gate error = sigsendproc(p, sigsend);
630Sstevel@tonic-gate if (error == 0 && sigsend->perm == 0)
640Sstevel@tonic-gate error = EPERM;
650Sstevel@tonic-gate }
660Sstevel@tonic-gate mutex_exit(&pidlock);
670Sstevel@tonic-gate } else {
680Sstevel@tonic-gate int nfound = 0;
690Sstevel@tonic-gate pid_t pgid;
700Sstevel@tonic-gate
710Sstevel@tonic-gate if (pid == 0)
720Sstevel@tonic-gate pgid = ttoproc(curthread)->p_pgrp;
730Sstevel@tonic-gate else
740Sstevel@tonic-gate pgid = -pid;
750Sstevel@tonic-gate
760Sstevel@tonic-gate error = 0;
770Sstevel@tonic-gate mutex_enter(&pidlock);
780Sstevel@tonic-gate for (p = pgfind(pgid); p && !error; p = p->p_pglink) {
790Sstevel@tonic-gate if (p->p_stat != SIDL) {
800Sstevel@tonic-gate nfound++;
810Sstevel@tonic-gate error = sigsendproc(p, sigsend);
820Sstevel@tonic-gate }
830Sstevel@tonic-gate }
840Sstevel@tonic-gate mutex_exit(&pidlock);
850Sstevel@tonic-gate if (nfound == 0)
860Sstevel@tonic-gate error = ESRCH;
870Sstevel@tonic-gate else if (error == 0 && sigsend->perm == 0)
880Sstevel@tonic-gate error = EPERM;
890Sstevel@tonic-gate }
900Sstevel@tonic-gate
91*2248Sraf return (error);
920Sstevel@tonic-gate }
930Sstevel@tonic-gate
940Sstevel@tonic-gate
950Sstevel@tonic-gate /*
960Sstevel@tonic-gate * for implementations that don't require binary compatibility,
970Sstevel@tonic-gate * the kill system call may be made into a library call to the
980Sstevel@tonic-gate * sigsend system call
990Sstevel@tonic-gate */
1000Sstevel@tonic-gate int
kill(pid_t pid,int sig)1010Sstevel@tonic-gate kill(pid_t pid, int sig)
1020Sstevel@tonic-gate {
103*2248Sraf int error;
1040Sstevel@tonic-gate sigsend_t v;
1050Sstevel@tonic-gate
1060Sstevel@tonic-gate bzero(&v, sizeof (v));
1070Sstevel@tonic-gate v.sig = sig;
1080Sstevel@tonic-gate v.checkperm = 1;
1090Sstevel@tonic-gate v.sicode = SI_USER;
110*2248Sraf if ((error = sigqkill(pid, &v)) != 0)
111*2248Sraf return (set_errno(error));
112*2248Sraf return (0);
1130Sstevel@tonic-gate }
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate /*
1160Sstevel@tonic-gate * The handling of small unions, like the sigval argument to sigqueue,
117*2248Sraf * is architecture dependent. We have adopted the convention that the
1180Sstevel@tonic-gate * value itself is passed in the storage which crosses the kernel
1190Sstevel@tonic-gate * protection boundary. This procedure will accept a scalar argument,
1200Sstevel@tonic-gate * and store it in the appropriate value member of the sigsend_t structure.
1210Sstevel@tonic-gate */
1220Sstevel@tonic-gate int
sigqueue(pid_t pid,int sig,void * value,int si_code,int block)123*2248Sraf sigqueue(pid_t pid, int sig, /* union sigval */ void *value,
124*2248Sraf int si_code, int block)
1250Sstevel@tonic-gate {
126*2248Sraf int error;
1270Sstevel@tonic-gate sigsend_t v;
1280Sstevel@tonic-gate sigqhdr_t *sqh;
1290Sstevel@tonic-gate proc_t *p = curproc;
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate /* The si_code value must indicate the signal will be queued */
132*2248Sraf if (pid <= 0 || !sigwillqueue(sig, si_code))
1330Sstevel@tonic-gate return (set_errno(EINVAL));
1340Sstevel@tonic-gate
135*2248Sraf if ((sqh = p->p_sigqhdr) == NULL) {
1360Sstevel@tonic-gate /* Allocate sigqueue pool first time */
1370Sstevel@tonic-gate sqh = sigqhdralloc(sizeof (sigqueue_t), _SIGQUEUE_MAX);
1380Sstevel@tonic-gate mutex_enter(&p->p_lock);
1390Sstevel@tonic-gate if (p->p_sigqhdr == NULL) {
1400Sstevel@tonic-gate /* hang the pool head on proc */
1410Sstevel@tonic-gate p->p_sigqhdr = sqh;
1420Sstevel@tonic-gate } else {
1430Sstevel@tonic-gate /* another lwp allocated the pool, free ours */
1440Sstevel@tonic-gate sigqhdrfree(sqh);
145*2248Sraf sqh = p->p_sigqhdr;
1460Sstevel@tonic-gate }
1470Sstevel@tonic-gate mutex_exit(&p->p_lock);
1480Sstevel@tonic-gate }
1490Sstevel@tonic-gate
150*2248Sraf do {
151*2248Sraf bzero(&v, sizeof (v));
152*2248Sraf v.sig = sig;
153*2248Sraf v.checkperm = 1;
154*2248Sraf v.sicode = si_code;
155*2248Sraf v.value.sival_ptr = value;
156*2248Sraf if ((error = sigqkill(pid, &v)) != EAGAIN || !block)
157*2248Sraf break;
158*2248Sraf /* block waiting for another chance to allocate a sigqueue_t */
159*2248Sraf mutex_enter(&sqh->sqb_lock);
160*2248Sraf while (sqh->sqb_count == 0) {
161*2248Sraf if (!cv_wait_sig(&sqh->sqb_cv, &sqh->sqb_lock)) {
162*2248Sraf error = EINTR;
163*2248Sraf break;
164*2248Sraf }
165*2248Sraf }
166*2248Sraf mutex_exit(&sqh->sqb_lock);
167*2248Sraf } while (error == EAGAIN);
1680Sstevel@tonic-gate
169*2248Sraf if (error)
170*2248Sraf return (set_errno(error));
171*2248Sraf return (0);
1720Sstevel@tonic-gate }
1730Sstevel@tonic-gate
1740Sstevel@tonic-gate #ifdef _SYSCALL32_IMPL
1750Sstevel@tonic-gate /*
1760Sstevel@tonic-gate * sigqueue32 - System call entry point for 32-bit callers on LP64 kernel,
1770Sstevel@tonic-gate * needed to handle the 32-bit sigvals as correctly as we can. We always
1780Sstevel@tonic-gate * assume that a 32-bit caller is passing an int. A 64-bit recipient
1790Sstevel@tonic-gate * that expects an int will therefore get it correctly. A 32-bit
1800Sstevel@tonic-gate * recipient will also get it correctly since siginfo_kto32() uses
1810Sstevel@tonic-gate * sival_int in the conversion. Since a 32-bit pointer has the same
1820Sstevel@tonic-gate * size and address in the sigval, it also converts correctly so that
1830Sstevel@tonic-gate * two 32-bit apps can exchange a pointer value. However, this means
1840Sstevel@tonic-gate * that a pointer sent by a 32-bit caller will be seen in the upper half
1850Sstevel@tonic-gate * by a 64-bit recipient, and only the upper half of a 64-bit pointer will
1860Sstevel@tonic-gate * be seen by a 32-bit recipient. This is the best solution that does
1870Sstevel@tonic-gate * not require severe hacking of the sigval union. Anyways, what it
1880Sstevel@tonic-gate * means to be sending pointers between processes with dissimilar
1890Sstevel@tonic-gate * models is unclear.
1900Sstevel@tonic-gate */
1910Sstevel@tonic-gate int
sigqueue32(pid_t pid,int sig,caddr32_t value,int si_code,int block)192*2248Sraf sigqueue32(pid_t pid, int sig, /* union sigval32 */ caddr32_t value,
193*2248Sraf int si_code, int block)
1940Sstevel@tonic-gate {
1950Sstevel@tonic-gate union sigval sv;
1960Sstevel@tonic-gate
1970Sstevel@tonic-gate bzero(&sv, sizeof (sv));
1980Sstevel@tonic-gate sv.sival_int = (int)value;
199*2248Sraf return (sigqueue(pid, sig, sv.sival_ptr, si_code, block));
2000Sstevel@tonic-gate }
2010Sstevel@tonic-gate #endif
202