1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 #include <sys/param.h> 34 #include <sys/types.h> 35 #include <sys/sysmacros.h> 36 #include <sys/systm.h> 37 #include <sys/user.h> 38 #include <sys/errno.h> 39 #include <sys/proc.h> 40 #include <sys/fault.h> 41 #include <sys/signal.h> 42 #include <sys/siginfo.h> 43 #include <sys/debug.h> 44 45 int 46 sigaction(int sig, struct sigaction *actp, struct sigaction *oactp) 47 { 48 struct sigaction act; 49 struct sigaction oact; 50 k_sigset_t set; 51 proc_t *p; 52 user_t *ua; 53 int sigcld_look = 0; 54 55 if (sig <= 0 || sig >= NSIG || 56 (actp != NULL && sigismember(&cantmask, sig))) 57 return (set_errno(EINVAL)); 58 59 /* 60 * act and oact might be the same address, so copyin act first. 61 */ 62 if (actp) { 63 #if defined(__sparc) 64 void (*handler)(); 65 #endif 66 if (copyin(actp, &act, sizeof (act))) 67 return (set_errno(EFAULT)); 68 #if defined(__sparc) 69 /* 70 * Check alignment of handler 71 */ 72 handler = act.sa_handler; 73 if (handler != SIG_IGN && handler != SIG_DFL && 74 ((uintptr_t)handler & 0x3) != 0) 75 return (set_errno(EINVAL)); 76 #endif 77 } 78 79 p = curproc; 80 ua = PTOU(p); 81 mutex_enter(&p->p_lock); 82 83 if (oactp) { 84 int flags; 85 void (*disp)(); 86 87 disp = ua->u_signal[sig - 1]; 88 89 flags = 0; 90 if (disp != SIG_DFL && disp != SIG_IGN) { 91 set = ua->u_sigmask[sig-1]; 92 if (sigismember(&p->p_siginfo, sig)) 93 flags |= SA_SIGINFO; 94 if (sigismember(&ua->u_sigrestart, sig)) 95 flags |= SA_RESTART; 96 if (sigismember(&ua->u_sigonstack, sig)) 97 flags |= SA_ONSTACK; 98 if (sigismember(&ua->u_sigresethand, sig)) 99 flags |= SA_RESETHAND; 100 if (sigismember(&ua->u_signodefer, sig)) 101 flags |= SA_NODEFER; 102 } else 103 sigemptyset(&set); 104 105 if (sig == SIGCLD) { 106 if (p->p_flag & SNOWAIT) 107 flags |= SA_NOCLDWAIT; 108 if (!(p->p_flag & SJCTL)) 109 flags |= SA_NOCLDSTOP; 110 } 111 112 oact.sa_handler = disp; 113 oact.sa_flags = flags; 114 sigktou(&set, &oact.sa_mask); 115 } 116 117 if (actp) { 118 if (sig == SIGCLD && 119 act.sa_handler != SIG_IGN && 120 act.sa_handler != SIG_DFL) 121 sigcld_look = 1; 122 123 sigutok(&act.sa_mask, &set); 124 setsigact(sig, act.sa_handler, set, act.sa_flags); 125 } 126 127 mutex_exit(&p->p_lock); 128 129 if (sigcld_look) 130 sigcld_repost(); 131 132 if (oactp && 133 copyout(&oact, oactp, sizeof (oact))) 134 return (set_errno(EFAULT)); 135 136 return (0); 137 } 138 139 #ifdef _SYSCALL32_IMPL 140 141 int 142 sigaction32(int sig, struct sigaction32 *actp, struct sigaction32 *oactp) 143 { 144 struct sigaction32 act32; 145 struct sigaction32 oact32; 146 k_sigset_t set; 147 proc_t *p; 148 user_t *ua; 149 int sigcld_look = 0; 150 151 if (sig <= 0 || sig >= NSIG || 152 (actp != NULL && sigismember(&cantmask, sig))) 153 return (set_errno(EINVAL)); 154 155 /* 156 * act and oact might be the same address, so copyin act first. 157 */ 158 if (actp) { 159 #if defined(__sparc) 160 void (*handler)(); 161 #endif 162 if (copyin(actp, &act32, sizeof (act32))) 163 return (set_errno(EFAULT)); 164 #if defined(__sparc) 165 /* 166 * Check alignment of handler 167 */ 168 handler = (void (*)())(uintptr_t)act32.sa_handler; 169 if (handler != SIG_IGN && handler != SIG_DFL && 170 ((uintptr_t)handler & 0x3) != 0) 171 return (set_errno(EINVAL)); 172 #endif 173 } 174 175 p = curproc; 176 ua = PTOU(p); 177 mutex_enter(&p->p_lock); 178 179 if (oactp) { 180 int flags; 181 void (*disp)(); 182 183 disp = ua->u_signal[sig - 1]; 184 185 flags = 0; 186 if (disp != SIG_DFL && disp != SIG_IGN) { 187 set = ua->u_sigmask[sig-1]; 188 if (sigismember(&p->p_siginfo, sig)) 189 flags |= SA_SIGINFO; 190 if (sigismember(&ua->u_sigrestart, sig)) 191 flags |= SA_RESTART; 192 if (sigismember(&ua->u_sigonstack, sig)) 193 flags |= SA_ONSTACK; 194 if (sigismember(&ua->u_sigresethand, sig)) 195 flags |= SA_RESETHAND; 196 if (sigismember(&ua->u_signodefer, sig)) 197 flags |= SA_NODEFER; 198 } else 199 sigemptyset(&set); 200 201 if (sig == SIGCLD) { 202 if (p->p_flag & SNOWAIT) 203 flags |= SA_NOCLDWAIT; 204 if (!(p->p_flag & SJCTL)) 205 flags |= SA_NOCLDSTOP; 206 } 207 208 oact32.sa_handler = (caddr32_t)(uintptr_t)disp; 209 oact32.sa_flags = flags; 210 sigktou(&set, &oact32.sa_mask); 211 } 212 213 if (actp) { 214 if (sig == SIGCLD && 215 act32.sa_handler != (caddr32_t)SIG_IGN && 216 act32.sa_handler != (caddr32_t)SIG_DFL) 217 sigcld_look = 1; 218 219 sigutok(&act32.sa_mask, &set); 220 setsigact(sig, (void (*)())(uintptr_t)act32.sa_handler, set, 221 act32.sa_flags); 222 } 223 224 mutex_exit(&p->p_lock); 225 226 if (sigcld_look) 227 sigcld_repost(); 228 229 if (oactp && 230 copyout(&oact32, oactp, sizeof (oact32))) 231 return (set_errno(EFAULT)); 232 233 return (0); 234 } 235 #endif /* _SYSCALL32_IMPL */ 236