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