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 * Copyright 2004 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 int sigcld_look = 0; 53 54 if (sig <= 0 || sig >= NSIG || 55 (actp != NULL && sigismember(&cantmask, sig))) 56 return (set_errno(EINVAL)); 57 58 /* 59 * act and oact might be the same address, so copyin act first. 60 */ 61 if (actp) { 62 #if defined(__sparc) 63 void (*handler)(); 64 #endif 65 if (copyin(actp, &act, sizeof (act))) 66 return (set_errno(EFAULT)); 67 #if defined(__sparc) 68 /* 69 * Check alignment of handler 70 */ 71 handler = act.sa_handler; 72 if (handler != SIG_IGN && handler != SIG_DFL && 73 ((uintptr_t)handler & 0x3) != 0) 74 return (set_errno(EINVAL)); 75 #endif 76 } 77 78 p = curproc; 79 mutex_enter(&p->p_lock); 80 81 if (oactp) { 82 int flags; 83 void (*disp)(); 84 85 disp = u.u_signal[sig - 1]; 86 87 flags = 0; 88 if (disp != SIG_DFL && disp != SIG_IGN) { 89 set = u.u_sigmask[sig-1]; 90 if (sigismember(&p->p_siginfo, sig)) 91 flags |= SA_SIGINFO; 92 if (sigismember(&u.u_sigrestart, sig)) 93 flags |= SA_RESTART; 94 if (sigismember(&u.u_sigonstack, sig)) 95 flags |= SA_ONSTACK; 96 if (sigismember(&u.u_sigresethand, sig)) 97 flags |= SA_RESETHAND; 98 if (sigismember(&u.u_signodefer, sig)) 99 flags |= SA_NODEFER; 100 } else 101 sigemptyset(&set); 102 103 if (sig == SIGCLD) { 104 if (p->p_flag & SNOWAIT) 105 flags |= SA_NOCLDWAIT; 106 if (!(p->p_flag & SJCTL)) 107 flags |= SA_NOCLDSTOP; 108 } 109 110 oact.sa_handler = disp; 111 oact.sa_flags = flags; 112 sigktou(&set, &oact.sa_mask); 113 } 114 115 if (actp) { 116 if (sig == SIGCLD && 117 act.sa_handler != SIG_IGN && 118 act.sa_handler != SIG_DFL) 119 sigcld_look = 1; 120 121 sigutok(&act.sa_mask, &set); 122 setsigact(sig, act.sa_handler, set, act.sa_flags); 123 } 124 125 mutex_exit(&p->p_lock); 126 127 if (sigcld_look) 128 sigcld_repost(); 129 130 if (oactp && 131 copyout(&oact, oactp, sizeof (oact))) 132 return (set_errno(EFAULT)); 133 134 return (0); 135 } 136 137 #ifdef _SYSCALL32_IMPL 138 139 int 140 sigaction32(int sig, struct sigaction32 *actp, struct sigaction32 *oactp) 141 { 142 struct sigaction32 act32; 143 struct sigaction32 oact32; 144 k_sigset_t set; 145 proc_t *p; 146 int sigcld_look = 0; 147 148 if (sig <= 0 || sig >= NSIG || 149 (actp != NULL && sigismember(&cantmask, sig))) 150 return (set_errno(EINVAL)); 151 152 /* 153 * act and oact might be the same address, so copyin act first. 154 */ 155 if (actp) { 156 #if defined(__sparc) 157 void (*handler)(); 158 #endif 159 if (copyin(actp, &act32, sizeof (act32))) 160 return (set_errno(EFAULT)); 161 #if defined(__sparc) 162 /* 163 * Check alignment of handler 164 */ 165 handler = (void (*)())act32.sa_handler; 166 if (handler != SIG_IGN && handler != SIG_DFL && 167 ((uintptr_t)handler & 0x3) != 0) 168 return (set_errno(EINVAL)); 169 #endif 170 } 171 172 p = curproc; 173 mutex_enter(&p->p_lock); 174 175 if (oactp) { 176 int flags; 177 void (*disp)(); 178 179 disp = u.u_signal[sig - 1]; 180 181 flags = 0; 182 if (disp != SIG_DFL && disp != SIG_IGN) { 183 set = u.u_sigmask[sig-1]; 184 if (sigismember(&p->p_siginfo, sig)) 185 flags |= SA_SIGINFO; 186 if (sigismember(&u.u_sigrestart, sig)) 187 flags |= SA_RESTART; 188 if (sigismember(&u.u_sigonstack, sig)) 189 flags |= SA_ONSTACK; 190 if (sigismember(&u.u_sigresethand, sig)) 191 flags |= SA_RESETHAND; 192 if (sigismember(&u.u_signodefer, sig)) 193 flags |= SA_NODEFER; 194 } else 195 sigemptyset(&set); 196 197 if (sig == SIGCLD) { 198 if (p->p_flag & SNOWAIT) 199 flags |= SA_NOCLDWAIT; 200 if (!(p->p_flag & SJCTL)) 201 flags |= SA_NOCLDSTOP; 202 } 203 204 oact32.sa_handler = (caddr32_t)(uintptr_t)disp; 205 oact32.sa_flags = flags; 206 sigktou(&set, &oact32.sa_mask); 207 } 208 209 if (actp) { 210 if (sig == SIGCLD && 211 act32.sa_handler != (caddr32_t)SIG_IGN && 212 act32.sa_handler != (caddr32_t)SIG_DFL) 213 sigcld_look = 1; 214 215 sigutok(&act32.sa_mask, &set); 216 setsigact(sig, (void (*)())(uintptr_t)act32.sa_handler, set, 217 act32.sa_flags); 218 } 219 220 mutex_exit(&p->p_lock); 221 222 if (sigcld_look) 223 sigcld_repost(); 224 225 if (oactp && 226 copyout(&oact32, oactp, sizeof (oact32))) 227 return (set_errno(EFAULT)); 228 229 return (0); 230 } 231 #endif /* _SYSCALL32_IMPL */ 232