4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 #include <sys/param.h>
30 #include <sys/types.h>
31 #include <sys/sysmacros.h>
32 #include <sys/systm.h>
33 #include <sys/errno.h>
35 #include <sys/procset.h>
36 #include <sys/fault.h>
37 #include <sys/signal.h>
38 #include <sys/siginfo.h>
39 #include <sys/debug.h>
41 extern rctl_hndl_t rc_process_sigqueue
;
44 sigqkill(pid_t pid
, sigsend_t
*sigsend
)
49 if ((uint_t
)sigsend
->sig
>= NSIG
)
55 setprocset(&set
, POP_AND
, P_ALL
, P_MYID
, P_ALL
, P_MYID
);
56 error
= sigsendset(&set
, sigsend
);
58 mutex_enter(&pidlock
);
59 if ((p
= prfind(pid
)) == NULL
|| p
->p_stat
== SIDL
)
62 error
= sigsendproc(p
, sigsend
);
63 if (error
== 0 && sigsend
->perm
== 0)
72 pgid
= ttoproc(curthread
)->p_pgrp
;
77 mutex_enter(&pidlock
);
78 for (p
= pgfind(pgid
); p
&& !error
; p
= p
->p_pglink
) {
79 if (p
->p_stat
!= SIDL
) {
81 error
= sigsendproc(p
, sigsend
);
87 else if (error
== 0 && sigsend
->perm
== 0)
96 * for implementations that don't require binary compatibility,
97 * the kill system call may be made into a library call to the
101 kill(pid_t pid
, int sig
)
106 bzero(&v
, sizeof (v
));
110 if ((error
= sigqkill(pid
, &v
)) != 0)
111 return (set_errno(error
));
116 * The handling of small unions, like the sigval argument to sigqueue,
117 * is architecture dependent. We have adopted the convention that the
118 * value itself is passed in the storage which crosses the kernel
119 * protection boundary. This procedure will accept a scalar argument,
120 * and store it in the appropriate value member of the sigsend_t structure.
123 sigqueue(pid_t pid
, int sig
, /* union sigval */ void *value
,
124 int si_code
, int block
)
131 /* The si_code value must indicate the signal will be queued */
132 if (pid
<= 0 || !sigwillqueue(sig
, si_code
))
133 return (set_errno(EINVAL
));
135 if ((sqh
= p
->p_sigqhdr
) == NULL
) {
138 mutex_enter(&p
->p_lock
);
139 sigqsz_max
= rctl_enforced_value(rc_process_sigqueue
,
141 mutex_exit(&p
->p_lock
);
143 /* Allocate sigqueue pool first time */
144 sqh
= sigqhdralloc(sizeof (sigqueue_t
), (uint_t
)sigqsz_max
);
145 mutex_enter(&p
->p_lock
);
146 if (p
->p_sigqhdr
== NULL
) {
147 /* hang the pool head on proc */
150 /* another lwp allocated the pool, free ours */
154 mutex_exit(&p
->p_lock
);
158 bzero(&v
, sizeof (v
));
162 v
.value
.sival_ptr
= value
;
163 if ((error
= sigqkill(pid
, &v
)) != EAGAIN
|| !block
)
165 /* block waiting for another chance to allocate a sigqueue_t */
166 mutex_enter(&sqh
->sqb_lock
);
167 while (sqh
->sqb_count
== 0) {
168 if (!cv_wait_sig(&sqh
->sqb_cv
, &sqh
->sqb_lock
)) {
173 mutex_exit(&sqh
->sqb_lock
);
174 } while (error
== EAGAIN
);
177 return (set_errno(error
));
181 #ifdef _SYSCALL32_IMPL
183 * sigqueue32 - System call entry point for 32-bit callers on LP64 kernel,
184 * needed to handle the 32-bit sigvals as correctly as we can. We always
185 * assume that a 32-bit caller is passing an int. A 64-bit recipient
186 * that expects an int will therefore get it correctly. A 32-bit
187 * recipient will also get it correctly since siginfo_kto32() uses
188 * sival_int in the conversion. Since a 32-bit pointer has the same
189 * size and address in the sigval, it also converts correctly so that
190 * two 32-bit apps can exchange a pointer value. However, this means
191 * that a pointer sent by a 32-bit caller will be seen in the upper half
192 * by a 64-bit recipient, and only the upper half of a 64-bit pointer will
193 * be seen by a 32-bit recipient. This is the best solution that does
194 * not require severe hacking of the sigval union. Anyways, what it
195 * means to be sending pointers between processes with dissimilar
199 sigqueue32(pid_t pid
, int sig
, /* union sigval32 */ caddr32_t value
,
200 int si_code
, int block
)
204 bzero(&sv
, sizeof (sv
));
205 sv
.sival_int
= (int)value
;
206 return (sigqueue(pid
, sig
, sv
.sival_ptr
, si_code
, block
));