ibcs2_signal.c revision 331643
1/*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1995 Scott Bartram 5 * Copyright (c) 1995 Steven Wallace 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include <sys/cdefs.h> 32__FBSDID("$FreeBSD: stable/11/sys/i386/ibcs2/ibcs2_signal.c 331643 2018-03-27 18:52:27Z dim $"); 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/lock.h> 37#include <sys/mutex.h> 38#include <sys/signalvar.h> 39#include <sys/syscallsubr.h> 40#include <sys/sysproto.h> 41 42#include <i386/ibcs2/ibcs2_types.h> 43#include <i386/ibcs2/ibcs2_signal.h> 44#include <i386/ibcs2/ibcs2_proto.h> 45#include <i386/ibcs2/ibcs2_xenix.h> 46#include <i386/ibcs2/ibcs2_util.h> 47 48#define sigemptyset(s) SIGEMPTYSET(*(s)) 49#define sigismember(s, n) SIGISMEMBER(*(s), n) 50#define sigaddset(s, n) SIGADDSET(*(s), n) 51 52#define ibcs2_sigmask(n) (1 << ((n) - 1)) 53#define ibcs2_sigemptyset(s) bzero((s), sizeof(*(s))) 54#define ibcs2_sigismember(s, n) (*(s) & ibcs2_sigmask(n)) 55#define ibcs2_sigaddset(s, n) (*(s) |= ibcs2_sigmask(n)) 56 57static void ibcs2_to_bsd_sigset(const ibcs2_sigset_t *, sigset_t *); 58static void bsd_to_ibcs2_sigset(const sigset_t *, ibcs2_sigset_t *); 59static void ibcs2_to_bsd_sigaction(struct ibcs2_sigaction *, 60 struct sigaction *); 61static void bsd_to_ibcs2_sigaction(struct sigaction *, 62 struct ibcs2_sigaction *); 63 64int bsd_to_ibcs2_sig[IBCS2_SIGTBLSZ] = { 65 IBCS2_SIGHUP, /* 1 */ 66 IBCS2_SIGINT, /* 2 */ 67 IBCS2_SIGQUIT, /* 3 */ 68 IBCS2_SIGILL, /* 4 */ 69 IBCS2_SIGTRAP, /* 5 */ 70 IBCS2_SIGABRT, /* 6 */ 71 IBCS2_SIGEMT, /* 7 */ 72 IBCS2_SIGFPE, /* 8 */ 73 IBCS2_SIGKILL, /* 9 */ 74 IBCS2_SIGBUS, /* 10 */ 75 IBCS2_SIGSEGV, /* 11 */ 76 IBCS2_SIGSYS, /* 12 */ 77 IBCS2_SIGPIPE, /* 13 */ 78 IBCS2_SIGALRM, /* 14 */ 79 IBCS2_SIGTERM, /* 15 */ 80 0, /* 16 - SIGURG */ 81 IBCS2_SIGSTOP, /* 17 */ 82 IBCS2_SIGTSTP, /* 18 */ 83 IBCS2_SIGCONT, /* 19 */ 84 IBCS2_SIGCLD, /* 20 */ 85 IBCS2_SIGTTIN, /* 21 */ 86 IBCS2_SIGTTOU, /* 22 */ 87 IBCS2_SIGPOLL, /* 23 */ 88 0, /* 24 - SIGXCPU */ 89 0, /* 25 - SIGXFSZ */ 90 IBCS2_SIGVTALRM, /* 26 */ 91 IBCS2_SIGPROF, /* 27 */ 92 IBCS2_SIGWINCH, /* 28 */ 93 0, /* 29 */ 94 IBCS2_SIGUSR1, /* 30 */ 95 IBCS2_SIGUSR2, /* 31 */ 96 0 /* 32 */ 97}; 98 99static int ibcs2_to_bsd_sig[IBCS2_SIGTBLSZ] = { 100 SIGHUP, /* 1 */ 101 SIGINT, /* 2 */ 102 SIGQUIT, /* 3 */ 103 SIGILL, /* 4 */ 104 SIGTRAP, /* 5 */ 105 SIGABRT, /* 6 */ 106 SIGEMT, /* 7 */ 107 SIGFPE, /* 8 */ 108 SIGKILL, /* 9 */ 109 SIGBUS, /* 10 */ 110 SIGSEGV, /* 11 */ 111 SIGSYS, /* 12 */ 112 SIGPIPE, /* 13 */ 113 SIGALRM, /* 14 */ 114 SIGTERM, /* 15 */ 115 SIGUSR1, /* 16 */ 116 SIGUSR2, /* 17 */ 117 SIGCHLD, /* 18 */ 118 0, /* 19 - SIGPWR */ 119 SIGWINCH, /* 20 */ 120 0, /* 21 */ 121 SIGIO, /* 22 */ 122 SIGSTOP, /* 23 */ 123 SIGTSTP, /* 24 */ 124 SIGCONT, /* 25 */ 125 SIGTTIN, /* 26 */ 126 SIGTTOU, /* 27 */ 127 SIGVTALRM, /* 28 */ 128 SIGPROF, /* 29 */ 129 0, /* 30 */ 130 0, /* 31 */ 131 0 /* 32 */ 132}; 133 134void 135ibcs2_to_bsd_sigset(iss, bss) 136 const ibcs2_sigset_t *iss; 137 sigset_t *bss; 138{ 139 int i, newsig; 140 141 sigemptyset(bss); 142 for (i = 1; i <= IBCS2_SIGTBLSZ; i++) { 143 if (ibcs2_sigismember(iss, i)) { 144 newsig = ibcs2_to_bsd_sig[_SIG_IDX(i)]; 145 if (newsig) 146 sigaddset(bss, newsig); 147 } 148 } 149} 150 151static void 152bsd_to_ibcs2_sigset(bss, iss) 153 const sigset_t *bss; 154 ibcs2_sigset_t *iss; 155{ 156 int i, newsig; 157 158 ibcs2_sigemptyset(iss); 159 for (i = 1; i <= IBCS2_SIGTBLSZ; i++) { 160 if (sigismember(bss, i)) { 161 newsig = bsd_to_ibcs2_sig[_SIG_IDX(i)]; 162 if (newsig) 163 ibcs2_sigaddset(iss, newsig); 164 } 165 } 166} 167 168static void 169ibcs2_to_bsd_sigaction(isa, bsa) 170 struct ibcs2_sigaction *isa; 171 struct sigaction *bsa; 172{ 173 174 bsa->sa_handler = isa->isa_handler; 175 ibcs2_to_bsd_sigset(&isa->isa_mask, &bsa->sa_mask); 176 bsa->sa_flags = 0; /* ??? SA_NODEFER */ 177 if ((isa->isa_flags & IBCS2_SA_NOCLDSTOP) != 0) 178 bsa->sa_flags |= SA_NOCLDSTOP; 179} 180 181static void 182bsd_to_ibcs2_sigaction(bsa, isa) 183 struct sigaction *bsa; 184 struct ibcs2_sigaction *isa; 185{ 186 187 isa->isa_handler = bsa->sa_handler; 188 bsd_to_ibcs2_sigset(&bsa->sa_mask, &isa->isa_mask); 189 isa->isa_flags = 0; 190 if ((bsa->sa_flags & SA_NOCLDSTOP) != 0) 191 isa->isa_flags |= IBCS2_SA_NOCLDSTOP; 192} 193 194int 195ibcs2_sigaction(struct thread *td, struct ibcs2_sigaction_args *uap) 196{ 197 struct ibcs2_sigaction isa; 198 struct sigaction nbsa, obsa; 199 struct sigaction *nbsap; 200 int error; 201 202 if (uap->act != NULL) { 203 if ((error = copyin(uap->act, &isa, sizeof(isa))) != 0) 204 return (error); 205 ibcs2_to_bsd_sigaction(&isa, &nbsa); 206 nbsap = &nbsa; 207 } else 208 nbsap = NULL; 209 if (uap->sig <= 0 || uap->sig > IBCS2_NSIG) 210 return (EINVAL); 211 error = kern_sigaction(td, ibcs2_to_bsd_sig[_SIG_IDX(uap->sig)], &nbsa, 212 &obsa, 0); 213 if (error == 0 && uap->oact != NULL) { 214 bsd_to_ibcs2_sigaction(&obsa, &isa); 215 error = copyout(&isa, uap->oact, sizeof(isa)); 216 } 217 return (error); 218} 219 220int 221ibcs2_sigsys(struct thread *td, struct ibcs2_sigsys_args *uap) 222{ 223 struct proc *p = td->td_proc; 224 struct sigaction sa; 225 int signum = IBCS2_SIGNO(uap->sig); 226 int error; 227 228 if (signum <= 0 || signum > IBCS2_NSIG) { 229 if (IBCS2_SIGCALL(uap->sig) == IBCS2_SIGNAL_MASK || 230 IBCS2_SIGCALL(uap->sig) == IBCS2_SIGSET_MASK) 231 td->td_retval[0] = (int)IBCS2_SIG_ERR; 232 return EINVAL; 233 } 234 signum = ibcs2_to_bsd_sig[_SIG_IDX(signum)]; 235 236 switch (IBCS2_SIGCALL(uap->sig)) { 237 case IBCS2_SIGSET_MASK: 238 /* 239 * Check for SIG_HOLD action. 240 * Otherwise, perform signal() except with different sa_flags. 241 */ 242 if (uap->fp != IBCS2_SIG_HOLD) { 243 /* add sig to mask before exececuting signal handler */ 244 sa.sa_flags = 0; 245 goto ibcs2_sigset; 246 } 247 /* else FALLTHROUGH to sighold */ 248 249 case IBCS2_SIGHOLD_MASK: 250 { 251 sigset_t mask; 252 253 SIGEMPTYSET(mask); 254 SIGADDSET(mask, signum); 255 return (kern_sigprocmask(td, SIG_BLOCK, &mask, NULL, 256 0)); 257 } 258 259 case IBCS2_SIGNAL_MASK: 260 { 261 struct sigaction osa; 262 263 /* do not automatically block signal */ 264 sa.sa_flags = SA_NODEFER; 265#ifdef SA_RESETHAND 266 if((signum != IBCS2_SIGILL) && 267 (signum != IBCS2_SIGTRAP) && 268 (signum != IBCS2_SIGPWR)) 269 /* set to SIG_DFL before executing handler */ 270 sa.sa_flags |= SA_RESETHAND; 271#endif 272 ibcs2_sigset: 273 sa.sa_handler = uap->fp; 274 sigemptyset(&sa.sa_mask); 275#if 0 276 if (signum != SIGALRM) 277 sa.sa_flags |= SA_RESTART; 278#endif 279 error = kern_sigaction(td, signum, &sa, &osa, 0); 280 if (error != 0) { 281 DPRINTF(("signal: sigaction failed: %d\n", 282 error)); 283 td->td_retval[0] = (int)IBCS2_SIG_ERR; 284 return (error); 285 } 286 td->td_retval[0] = (int)osa.sa_handler; 287 288 /* special sigset() check */ 289 if(IBCS2_SIGCALL(uap->sig) == IBCS2_SIGSET_MASK) { 290 PROC_LOCK(p); 291 /* check to make sure signal is not blocked */ 292 if(sigismember(&td->td_sigmask, signum)) { 293 /* return SIG_HOLD and unblock signal*/ 294 td->td_retval[0] = (int)IBCS2_SIG_HOLD; 295 SIGDELSET(td->td_sigmask, signum); 296 signotify(td); 297 } 298 PROC_UNLOCK(p); 299 } 300 301 return 0; 302 } 303 304 case IBCS2_SIGRELSE_MASK: 305 { 306 sigset_t mask; 307 308 SIGEMPTYSET(mask); 309 SIGADDSET(mask, signum); 310 return (kern_sigprocmask(td, SIG_UNBLOCK, &mask, NULL, 311 0)); 312 } 313 314 case IBCS2_SIGIGNORE_MASK: 315 { 316 sa.sa_handler = SIG_IGN; 317 sigemptyset(&sa.sa_mask); 318 sa.sa_flags = 0; 319 error = kern_sigaction(td, signum, &sa, NULL, 0); 320 if (error != 0) 321 DPRINTF(("sigignore: sigaction failed\n")); 322 return (error); 323 } 324 325 case IBCS2_SIGPAUSE_MASK: 326 { 327 sigset_t mask; 328 329 PROC_LOCK(p); 330 mask = td->td_sigmask; 331 PROC_UNLOCK(p); 332 SIGDELSET(mask, signum); 333 return kern_sigsuspend(td, mask); 334 } 335 336 default: 337 return ENOSYS; 338 } 339} 340 341int 342ibcs2_sigprocmask(struct thread *td, struct ibcs2_sigprocmask_args *uap) 343{ 344 ibcs2_sigset_t iss; 345 sigset_t oss, nss; 346 sigset_t *nssp; 347 int error, how; 348 349 switch (uap->how) { 350 case IBCS2_SIG_BLOCK: 351 how = SIG_BLOCK; 352 break; 353 case IBCS2_SIG_UNBLOCK: 354 how = SIG_UNBLOCK; 355 break; 356 case IBCS2_SIG_SETMASK: 357 how = SIG_SETMASK; 358 break; 359 default: 360 return (EINVAL); 361 } 362 if (uap->set != NULL) { 363 if ((error = copyin(uap->set, &iss, sizeof(iss))) != 0) 364 return error; 365 ibcs2_to_bsd_sigset(&iss, &nss); 366 nssp = &nss; 367 } else 368 nssp = NULL; 369 error = kern_sigprocmask(td, how, nssp, &oss, 0); 370 if (error == 0 && uap->oset != NULL) { 371 bsd_to_ibcs2_sigset(&oss, &iss); 372 error = copyout(&iss, uap->oset, sizeof(iss)); 373 } 374 return (error); 375} 376 377int 378ibcs2_sigpending(struct thread *td, struct ibcs2_sigpending_args *uap) 379{ 380 struct proc *p = td->td_proc; 381 sigset_t bss; 382 ibcs2_sigset_t iss; 383 384 PROC_LOCK(p); 385 bss = td->td_siglist; 386 SIGSETOR(bss, p->p_siglist); 387 SIGSETAND(bss, td->td_sigmask); 388 PROC_UNLOCK(p); 389 bsd_to_ibcs2_sigset(&bss, &iss); 390 391 return copyout(&iss, uap->mask, sizeof(iss)); 392} 393 394int 395ibcs2_sigsuspend(struct thread *td, struct ibcs2_sigsuspend_args *uap) 396{ 397 ibcs2_sigset_t sss; 398 sigset_t bss; 399 int error; 400 401 if ((error = copyin(uap->mask, &sss, sizeof(sss))) != 0) 402 return error; 403 404 ibcs2_to_bsd_sigset(&sss, &bss); 405 return kern_sigsuspend(td, bss); 406} 407 408int 409ibcs2_pause(struct thread *td, struct ibcs2_pause_args *uap) 410{ 411 sigset_t mask; 412 413 PROC_LOCK(td->td_proc); 414 mask = td->td_sigmask; 415 PROC_UNLOCK(td->td_proc); 416 return kern_sigsuspend(td, mask); 417} 418 419int 420ibcs2_kill(struct thread *td, struct ibcs2_kill_args *uap) 421{ 422 struct kill_args ka; 423 424 if (uap->signo <= 0 || uap->signo > IBCS2_NSIG) 425 return (EINVAL); 426 ka.pid = uap->pid; 427 ka.signum = ibcs2_to_bsd_sig[_SIG_IDX(uap->signo)]; 428 return sys_kill(td, &ka); 429} 430