xref: /titanic_44/usr/src/uts/common/syscall/sigaction.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
34*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
35*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/systm.h>
37*7c478bd9Sstevel@tonic-gate #include <sys/user.h>
38*7c478bd9Sstevel@tonic-gate #include <sys/errno.h>
39*7c478bd9Sstevel@tonic-gate #include <sys/proc.h>
40*7c478bd9Sstevel@tonic-gate #include <sys/fault.h>
41*7c478bd9Sstevel@tonic-gate #include <sys/signal.h>
42*7c478bd9Sstevel@tonic-gate #include <sys/siginfo.h>
43*7c478bd9Sstevel@tonic-gate #include <sys/debug.h>
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate int
46*7c478bd9Sstevel@tonic-gate sigaction(int sig, struct sigaction *actp, struct sigaction *oactp)
47*7c478bd9Sstevel@tonic-gate {
48*7c478bd9Sstevel@tonic-gate 	struct sigaction act;
49*7c478bd9Sstevel@tonic-gate 	struct sigaction oact;
50*7c478bd9Sstevel@tonic-gate 	k_sigset_t set;
51*7c478bd9Sstevel@tonic-gate 	proc_t *p;
52*7c478bd9Sstevel@tonic-gate 	int sigcld_look = 0;
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate 	if (sig <= 0 || sig >= NSIG ||
55*7c478bd9Sstevel@tonic-gate 	    (actp != NULL && sigismember(&cantmask, sig)))
56*7c478bd9Sstevel@tonic-gate 		return (set_errno(EINVAL));
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate 	/*
59*7c478bd9Sstevel@tonic-gate 	 * act and oact might be the same address, so copyin act first.
60*7c478bd9Sstevel@tonic-gate 	 */
61*7c478bd9Sstevel@tonic-gate 	if (actp) {
62*7c478bd9Sstevel@tonic-gate #if defined(__sparc)
63*7c478bd9Sstevel@tonic-gate 		void (*handler)();
64*7c478bd9Sstevel@tonic-gate #endif
65*7c478bd9Sstevel@tonic-gate 		if (copyin(actp, &act, sizeof (act)))
66*7c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
67*7c478bd9Sstevel@tonic-gate #if defined(__sparc)
68*7c478bd9Sstevel@tonic-gate 		/*
69*7c478bd9Sstevel@tonic-gate 		 * Check alignment of handler
70*7c478bd9Sstevel@tonic-gate 		 */
71*7c478bd9Sstevel@tonic-gate 		handler = act.sa_handler;
72*7c478bd9Sstevel@tonic-gate 		if (handler != SIG_IGN && handler != SIG_DFL &&
73*7c478bd9Sstevel@tonic-gate 		    ((uintptr_t)handler & 0x3) != 0)
74*7c478bd9Sstevel@tonic-gate 			return (set_errno(EINVAL));
75*7c478bd9Sstevel@tonic-gate #endif
76*7c478bd9Sstevel@tonic-gate 	}
77*7c478bd9Sstevel@tonic-gate 
78*7c478bd9Sstevel@tonic-gate 	p = curproc;
79*7c478bd9Sstevel@tonic-gate 	mutex_enter(&p->p_lock);
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate 	if (oactp) {
82*7c478bd9Sstevel@tonic-gate 		int flags;
83*7c478bd9Sstevel@tonic-gate 		void (*disp)();
84*7c478bd9Sstevel@tonic-gate 
85*7c478bd9Sstevel@tonic-gate 		disp = u.u_signal[sig - 1];
86*7c478bd9Sstevel@tonic-gate 
87*7c478bd9Sstevel@tonic-gate 		flags = 0;
88*7c478bd9Sstevel@tonic-gate 		if (disp != SIG_DFL && disp != SIG_IGN) {
89*7c478bd9Sstevel@tonic-gate 			set = u.u_sigmask[sig-1];
90*7c478bd9Sstevel@tonic-gate 			if (sigismember(&p->p_siginfo, sig))
91*7c478bd9Sstevel@tonic-gate 				flags |= SA_SIGINFO;
92*7c478bd9Sstevel@tonic-gate 			if (sigismember(&u.u_sigrestart, sig))
93*7c478bd9Sstevel@tonic-gate 				flags |= SA_RESTART;
94*7c478bd9Sstevel@tonic-gate 			if (sigismember(&u.u_sigonstack, sig))
95*7c478bd9Sstevel@tonic-gate 				flags |= SA_ONSTACK;
96*7c478bd9Sstevel@tonic-gate 			if (sigismember(&u.u_sigresethand, sig))
97*7c478bd9Sstevel@tonic-gate 				flags |= SA_RESETHAND;
98*7c478bd9Sstevel@tonic-gate 			if (sigismember(&u.u_signodefer, sig))
99*7c478bd9Sstevel@tonic-gate 				flags |= SA_NODEFER;
100*7c478bd9Sstevel@tonic-gate 		} else
101*7c478bd9Sstevel@tonic-gate 			sigemptyset(&set);
102*7c478bd9Sstevel@tonic-gate 
103*7c478bd9Sstevel@tonic-gate 		if (sig == SIGCLD) {
104*7c478bd9Sstevel@tonic-gate 			if (p->p_flag & SNOWAIT)
105*7c478bd9Sstevel@tonic-gate 				flags |= SA_NOCLDWAIT;
106*7c478bd9Sstevel@tonic-gate 			if (!(p->p_flag & SJCTL))
107*7c478bd9Sstevel@tonic-gate 				flags |= SA_NOCLDSTOP;
108*7c478bd9Sstevel@tonic-gate 		}
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate 		oact.sa_handler = disp;
111*7c478bd9Sstevel@tonic-gate 		oact.sa_flags = flags;
112*7c478bd9Sstevel@tonic-gate 		sigktou(&set, &oact.sa_mask);
113*7c478bd9Sstevel@tonic-gate 	}
114*7c478bd9Sstevel@tonic-gate 
115*7c478bd9Sstevel@tonic-gate 	if (actp) {
116*7c478bd9Sstevel@tonic-gate 		if (sig == SIGCLD &&
117*7c478bd9Sstevel@tonic-gate 		    act.sa_handler != SIG_IGN &&
118*7c478bd9Sstevel@tonic-gate 		    act.sa_handler != SIG_DFL)
119*7c478bd9Sstevel@tonic-gate 			sigcld_look = 1;
120*7c478bd9Sstevel@tonic-gate 
121*7c478bd9Sstevel@tonic-gate 		sigutok(&act.sa_mask, &set);
122*7c478bd9Sstevel@tonic-gate 		setsigact(sig, act.sa_handler, set, act.sa_flags);
123*7c478bd9Sstevel@tonic-gate 	}
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate 	mutex_exit(&p->p_lock);
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate 	if (sigcld_look)
128*7c478bd9Sstevel@tonic-gate 		sigcld_repost();
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate 	if (oactp &&
131*7c478bd9Sstevel@tonic-gate 	    copyout(&oact, oactp, sizeof (oact)))
132*7c478bd9Sstevel@tonic-gate 		return (set_errno(EFAULT));
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate 	return (0);
135*7c478bd9Sstevel@tonic-gate }
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate #ifdef _SYSCALL32_IMPL
138*7c478bd9Sstevel@tonic-gate 
139*7c478bd9Sstevel@tonic-gate int
140*7c478bd9Sstevel@tonic-gate sigaction32(int sig, struct sigaction32 *actp, struct sigaction32 *oactp)
141*7c478bd9Sstevel@tonic-gate {
142*7c478bd9Sstevel@tonic-gate 	struct sigaction32 act32;
143*7c478bd9Sstevel@tonic-gate 	struct sigaction32 oact32;
144*7c478bd9Sstevel@tonic-gate 	k_sigset_t set;
145*7c478bd9Sstevel@tonic-gate 	proc_t *p;
146*7c478bd9Sstevel@tonic-gate 	int sigcld_look = 0;
147*7c478bd9Sstevel@tonic-gate 
148*7c478bd9Sstevel@tonic-gate 	if (sig <= 0 || sig >= NSIG ||
149*7c478bd9Sstevel@tonic-gate 	    (actp != NULL && sigismember(&cantmask, sig)))
150*7c478bd9Sstevel@tonic-gate 		return (set_errno(EINVAL));
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate 	/*
153*7c478bd9Sstevel@tonic-gate 	 * act and oact might be the same address, so copyin act first.
154*7c478bd9Sstevel@tonic-gate 	 */
155*7c478bd9Sstevel@tonic-gate 	if (actp) {
156*7c478bd9Sstevel@tonic-gate #if defined(__sparc)
157*7c478bd9Sstevel@tonic-gate 		void (*handler)();
158*7c478bd9Sstevel@tonic-gate #endif
159*7c478bd9Sstevel@tonic-gate 		if (copyin(actp, &act32, sizeof (act32)))
160*7c478bd9Sstevel@tonic-gate 			return (set_errno(EFAULT));
161*7c478bd9Sstevel@tonic-gate #if defined(__sparc)
162*7c478bd9Sstevel@tonic-gate 		/*
163*7c478bd9Sstevel@tonic-gate 		 * Check alignment of handler
164*7c478bd9Sstevel@tonic-gate 		 */
165*7c478bd9Sstevel@tonic-gate 		handler = (void (*)())act32.sa_handler;
166*7c478bd9Sstevel@tonic-gate 		if (handler != SIG_IGN && handler != SIG_DFL &&
167*7c478bd9Sstevel@tonic-gate 		    ((uintptr_t)handler & 0x3) != 0)
168*7c478bd9Sstevel@tonic-gate 			return (set_errno(EINVAL));
169*7c478bd9Sstevel@tonic-gate #endif
170*7c478bd9Sstevel@tonic-gate 	}
171*7c478bd9Sstevel@tonic-gate 
172*7c478bd9Sstevel@tonic-gate 	p = curproc;
173*7c478bd9Sstevel@tonic-gate 	mutex_enter(&p->p_lock);
174*7c478bd9Sstevel@tonic-gate 
175*7c478bd9Sstevel@tonic-gate 	if (oactp) {
176*7c478bd9Sstevel@tonic-gate 		int flags;
177*7c478bd9Sstevel@tonic-gate 		void (*disp)();
178*7c478bd9Sstevel@tonic-gate 
179*7c478bd9Sstevel@tonic-gate 		disp = u.u_signal[sig - 1];
180*7c478bd9Sstevel@tonic-gate 
181*7c478bd9Sstevel@tonic-gate 		flags = 0;
182*7c478bd9Sstevel@tonic-gate 		if (disp != SIG_DFL && disp != SIG_IGN) {
183*7c478bd9Sstevel@tonic-gate 			set = u.u_sigmask[sig-1];
184*7c478bd9Sstevel@tonic-gate 			if (sigismember(&p->p_siginfo, sig))
185*7c478bd9Sstevel@tonic-gate 				flags |= SA_SIGINFO;
186*7c478bd9Sstevel@tonic-gate 			if (sigismember(&u.u_sigrestart, sig))
187*7c478bd9Sstevel@tonic-gate 				flags |= SA_RESTART;
188*7c478bd9Sstevel@tonic-gate 			if (sigismember(&u.u_sigonstack, sig))
189*7c478bd9Sstevel@tonic-gate 				flags |= SA_ONSTACK;
190*7c478bd9Sstevel@tonic-gate 			if (sigismember(&u.u_sigresethand, sig))
191*7c478bd9Sstevel@tonic-gate 				flags |= SA_RESETHAND;
192*7c478bd9Sstevel@tonic-gate 			if (sigismember(&u.u_signodefer, sig))
193*7c478bd9Sstevel@tonic-gate 				flags |= SA_NODEFER;
194*7c478bd9Sstevel@tonic-gate 		} else
195*7c478bd9Sstevel@tonic-gate 			sigemptyset(&set);
196*7c478bd9Sstevel@tonic-gate 
197*7c478bd9Sstevel@tonic-gate 		if (sig == SIGCLD) {
198*7c478bd9Sstevel@tonic-gate 			if (p->p_flag & SNOWAIT)
199*7c478bd9Sstevel@tonic-gate 				flags |= SA_NOCLDWAIT;
200*7c478bd9Sstevel@tonic-gate 			if (!(p->p_flag & SJCTL))
201*7c478bd9Sstevel@tonic-gate 				flags |= SA_NOCLDSTOP;
202*7c478bd9Sstevel@tonic-gate 		}
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate 		oact32.sa_handler = (caddr32_t)(uintptr_t)disp;
205*7c478bd9Sstevel@tonic-gate 		oact32.sa_flags = flags;
206*7c478bd9Sstevel@tonic-gate 		sigktou(&set, &oact32.sa_mask);
207*7c478bd9Sstevel@tonic-gate 	}
208*7c478bd9Sstevel@tonic-gate 
209*7c478bd9Sstevel@tonic-gate 	if (actp) {
210*7c478bd9Sstevel@tonic-gate 		if (sig == SIGCLD &&
211*7c478bd9Sstevel@tonic-gate 		    act32.sa_handler != (caddr32_t)SIG_IGN &&
212*7c478bd9Sstevel@tonic-gate 		    act32.sa_handler != (caddr32_t)SIG_DFL)
213*7c478bd9Sstevel@tonic-gate 			sigcld_look = 1;
214*7c478bd9Sstevel@tonic-gate 
215*7c478bd9Sstevel@tonic-gate 		sigutok(&act32.sa_mask, &set);
216*7c478bd9Sstevel@tonic-gate 		setsigact(sig, (void (*)())(uintptr_t)act32.sa_handler, set,
217*7c478bd9Sstevel@tonic-gate 		    act32.sa_flags);
218*7c478bd9Sstevel@tonic-gate 	}
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate 	mutex_exit(&p->p_lock);
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate 	if (sigcld_look)
223*7c478bd9Sstevel@tonic-gate 		sigcld_repost();
224*7c478bd9Sstevel@tonic-gate 
225*7c478bd9Sstevel@tonic-gate 	if (oactp &&
226*7c478bd9Sstevel@tonic-gate 	    copyout(&oact32, oactp, sizeof (oact32)))
227*7c478bd9Sstevel@tonic-gate 		return (set_errno(EFAULT));
228*7c478bd9Sstevel@tonic-gate 
229*7c478bd9Sstevel@tonic-gate 	return (0);
230*7c478bd9Sstevel@tonic-gate }
231*7c478bd9Sstevel@tonic-gate #endif /* _SYSCALL32_IMPL */
232