Annotation of sys/compat/ibcs2/ibcs2_signal.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: ibcs2_signal.c,v 1.7 2002/03/14 01:26:50 millert Exp $ */
! 2: /* $NetBSD: ibcs2_signal.c,v 1.8 1996/05/03 17:05:27 christos Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1995 Scott Bartram
! 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/param.h>
! 32: #include <sys/systm.h>
! 33: #include <sys/namei.h>
! 34: #include <sys/proc.h>
! 35: #include <sys/filedesc.h>
! 36: #include <sys/ioctl.h>
! 37: #include <sys/mount.h>
! 38: #include <sys/kernel.h>
! 39: #include <sys/signal.h>
! 40: #include <sys/signalvar.h>
! 41: #include <sys/malloc.h>
! 42:
! 43: #include <sys/syscallargs.h>
! 44:
! 45: #include <compat/ibcs2/ibcs2_types.h>
! 46: #include <compat/ibcs2/ibcs2_signal.h>
! 47: #include <compat/ibcs2/ibcs2_syscallargs.h>
! 48: #include <compat/ibcs2/ibcs2_util.h>
! 49:
! 50: #define sigemptyset(s) bzero((s), sizeof(*(s)))
! 51: #define sigismember(s, n) (*(s) & sigmask(n))
! 52: #define sigaddset(s, n) (*(s) |= sigmask(n))
! 53:
! 54: #define ibcs2_sigmask(n) (1 << ((n) - 1))
! 55: #define ibcs2_sigemptyset(s) bzero((s), sizeof(*(s)))
! 56: #define ibcs2_sigismember(s, n) (*(s) & ibcs2_sigmask(n))
! 57: #define ibcs2_sigaddset(s, n) (*(s) |= ibcs2_sigmask(n))
! 58:
! 59: int bsd_to_ibcs2_sig[] = {
! 60: 0, /* 0 */
! 61: IBCS2_SIGHUP, /* 1 */
! 62: IBCS2_SIGINT, /* 2 */
! 63: IBCS2_SIGQUIT, /* 3 */
! 64: IBCS2_SIGILL, /* 4 */
! 65: IBCS2_SIGTRAP, /* 5 */
! 66: IBCS2_SIGABRT, /* 6 */
! 67: IBCS2_SIGEMT, /* 7 */
! 68: IBCS2_SIGFPE, /* 8 */
! 69: IBCS2_SIGKILL, /* 9 */
! 70: IBCS2_SIGBUS, /* 10 */
! 71: IBCS2_SIGSEGV, /* 11 */
! 72: IBCS2_SIGSYS, /* 12 */
! 73: IBCS2_SIGPIPE, /* 13 */
! 74: IBCS2_SIGALRM, /* 14 */
! 75: IBCS2_SIGTERM, /* 15 */
! 76: 0, /* 16 - SIGURG */
! 77: IBCS2_SIGSTOP, /* 17 */
! 78: IBCS2_SIGTSTP, /* 18 */
! 79: IBCS2_SIGCONT, /* 19 */
! 80: IBCS2_SIGCLD, /* 20 */
! 81: IBCS2_SIGTTIN, /* 21 */
! 82: IBCS2_SIGTTOU, /* 22 */
! 83: IBCS2_SIGPOLL, /* 23 */
! 84: 0, /* 24 - SIGXCPU */
! 85: 0, /* 25 - SIGXFSZ */
! 86: IBCS2_SIGVTALRM, /* 26 */
! 87: IBCS2_SIGPROF, /* 27 */
! 88: IBCS2_SIGWINCH, /* 28 */
! 89: 0, /* 29 */
! 90: IBCS2_SIGUSR1, /* 30 */
! 91: IBCS2_SIGUSR2, /* 31 */
! 92: };
! 93:
! 94: int ibcs2_to_bsd_sig[] = {
! 95: 0, /* 0 */
! 96: SIGHUP, /* 1 */
! 97: SIGINT, /* 2 */
! 98: SIGQUIT, /* 3 */
! 99: SIGILL, /* 4 */
! 100: SIGTRAP, /* 5 */
! 101: SIGABRT, /* 6 */
! 102: SIGEMT, /* 7 */
! 103: SIGFPE, /* 8 */
! 104: SIGKILL, /* 9 */
! 105: SIGBUS, /* 10 */
! 106: SIGSEGV, /* 11 */
! 107: SIGSYS, /* 12 */
! 108: SIGPIPE, /* 13 */
! 109: SIGALRM, /* 14 */
! 110: SIGTERM, /* 15 */
! 111: SIGUSR1, /* 16 */
! 112: SIGUSR2, /* 17 */
! 113: SIGCHLD, /* 18 */
! 114: 0, /* 19 - SIGPWR */
! 115: SIGWINCH, /* 20 */
! 116: 0, /* 21 */
! 117: SIGIO, /* 22 */
! 118: SIGSTOP, /* 23 */
! 119: SIGTSTP, /* 24 */
! 120: SIGCONT, /* 25 */
! 121: SIGTTIN, /* 26 */
! 122: SIGTTOU, /* 27 */
! 123: SIGVTALRM, /* 28 */
! 124: SIGPROF, /* 29 */
! 125: 0, /* 30 */
! 126: 0, /* 31 */
! 127: };
! 128:
! 129: void ibcs2_to_bsd_sigset(const ibcs2_sigset_t *, sigset_t *);
! 130: void bsd_to_ibcs2_sigset(const sigset_t *, ibcs2_sigset_t *);
! 131: void ibcs2_to_bsd_sigaction(struct ibcs2_sigaction *,
! 132: struct sigaction *);
! 133: void bsd_to_ibcs2_sigaction(struct sigaction *, struct ibcs2_sigaction *);
! 134:
! 135: void
! 136: ibcs2_to_bsd_sigset(iss, bss)
! 137: const ibcs2_sigset_t *iss;
! 138: sigset_t *bss;
! 139: {
! 140: int i, newsig;
! 141:
! 142: sigemptyset(bss);
! 143: for (i = 1; i < IBCS2_NSIG; i++) {
! 144: if (ibcs2_sigismember(iss, i)) {
! 145: newsig = ibcs2_to_bsd_sig[i];
! 146: if (newsig)
! 147: sigaddset(bss, newsig);
! 148: }
! 149: }
! 150: }
! 151:
! 152: void
! 153: bsd_to_ibcs2_sigset(bss, iss)
! 154: const sigset_t *bss;
! 155: ibcs2_sigset_t *iss;
! 156: {
! 157: int i, newsig;
! 158:
! 159: ibcs2_sigemptyset(iss);
! 160: for (i = 1; i < NSIG; i++) {
! 161: if (sigismember(bss, i)) {
! 162: newsig = bsd_to_ibcs2_sig[i];
! 163: if (newsig)
! 164: ibcs2_sigaddset(iss, newsig);
! 165: }
! 166: }
! 167: }
! 168:
! 169: void
! 170: ibcs2_to_bsd_sigaction(isa, bsa)
! 171: struct ibcs2_sigaction *isa;
! 172: struct sigaction *bsa;
! 173: {
! 174:
! 175: bsa->sa_handler = isa->sa__handler;
! 176: ibcs2_to_bsd_sigset(&isa->sa_mask, &bsa->sa_mask);
! 177: bsa->sa_flags = 0;
! 178: if ((isa->sa_flags & IBCS2_SA_NOCLDSTOP) != 0)
! 179: bsa->sa_flags |= SA_NOCLDSTOP;
! 180: }
! 181:
! 182: void
! 183: bsd_to_ibcs2_sigaction(bsa, isa)
! 184: struct sigaction *bsa;
! 185: struct ibcs2_sigaction *isa;
! 186: {
! 187:
! 188: isa->sa__handler = bsa->sa_handler;
! 189: bsd_to_ibcs2_sigset(&bsa->sa_mask, &isa->sa_mask);
! 190: isa->sa_flags = 0;
! 191: if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
! 192: isa->sa_flags |= IBCS2_SA_NOCLDSTOP;
! 193: }
! 194:
! 195: int
! 196: ibcs2_sys_sigaction(p, v, retval)
! 197: register struct proc *p;
! 198: void *v;
! 199: register_t *retval;
! 200: {
! 201: struct ibcs2_sys_sigaction_args /* {
! 202: syscallarg(int) signum;
! 203: syscallarg(struct ibcs2_sigaction *) nsa;
! 204: syscallarg(struct ibcs2_sigaction *) osa;
! 205: } */ *uap = v;
! 206: struct ibcs2_sigaction *nisa, *oisa, tmpisa;
! 207: struct sigaction *nbsa, *obsa, tmpbsa;
! 208: struct sys_sigaction_args sa;
! 209: caddr_t sg;
! 210: int error;
! 211:
! 212: if (SCARG(uap, signum) < 0 || SCARG(uap, signum) >= IBCS2_NSIG)
! 213: return (EINVAL);
! 214:
! 215: sg = stackgap_init(p->p_emul);
! 216: nisa = SCARG(uap, nsa);
! 217: oisa = SCARG(uap, osa);
! 218:
! 219: if (oisa != NULL)
! 220: obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
! 221: else
! 222: obsa = NULL;
! 223:
! 224: if (nisa != NULL) {
! 225: nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
! 226: if ((error = copyin(nisa, &tmpisa, sizeof(tmpisa))) != 0)
! 227: return error;
! 228: ibcs2_to_bsd_sigaction(&tmpisa, &tmpbsa);
! 229: if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
! 230: return error;
! 231: } else
! 232: nbsa = NULL;
! 233:
! 234: SCARG(&sa, signum) = ibcs2_to_bsd_sig[SCARG(uap, signum)];
! 235: SCARG(&sa, nsa) = nbsa;
! 236: SCARG(&sa, osa) = obsa;
! 237:
! 238: if ((error = sys_sigaction(p, &sa, retval)) != 0)
! 239: return error;
! 240:
! 241: if (oisa != NULL) {
! 242: if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
! 243: return error;
! 244: bsd_to_ibcs2_sigaction(&tmpbsa, &tmpisa);
! 245: if ((error = copyout(&tmpisa, oisa, sizeof(tmpisa))) != 0)
! 246: return error;
! 247: }
! 248:
! 249: return 0;
! 250: }
! 251:
! 252: int
! 253: ibcs2_sys_sigsys(p, v, retval)
! 254: register struct proc *p;
! 255: void *v;
! 256: register_t *retval;
! 257: {
! 258: struct ibcs2_sys_sigsys_args /* {
! 259: syscallarg(int) sig;
! 260: syscallarg(ibcs2_sig_t) fp;
! 261: } */ *uap = v;
! 262: int signum, error;
! 263: caddr_t sg = stackgap_init(p->p_emul);
! 264:
! 265: signum = IBCS2_SIGNO(SCARG(uap, sig));
! 266: if (signum < 0 || signum >= IBCS2_NSIG) {
! 267: if (IBCS2_SIGCALL(SCARG(uap, sig)) == IBCS2_SIGNAL_MASK ||
! 268: IBCS2_SIGCALL(SCARG(uap, sig)) == IBCS2_SIGSET_MASK)
! 269: *retval = (int)IBCS2_SIG_ERR;
! 270: return EINVAL;
! 271: }
! 272: signum = ibcs2_to_bsd_sig[signum];
! 273:
! 274: switch (IBCS2_SIGCALL(SCARG(uap, sig))) {
! 275: /*
! 276: * sigset is identical to signal() except that SIG_HOLD is allowed as
! 277: * an action.
! 278: */
! 279: case IBCS2_SIGSET_MASK:
! 280: /*
! 281: * sigset is identical to signal() except
! 282: * that SIG_HOLD is allowed as
! 283: * an action.
! 284: */
! 285: if (SCARG(uap, fp) == IBCS2_SIG_HOLD) {
! 286: struct sys_sigprocmask_args sa;
! 287:
! 288: SCARG(&sa, how) = SIG_BLOCK;
! 289: SCARG(&sa, mask) = sigmask(signum);
! 290: return sys_sigprocmask(p, &sa, retval);
! 291: }
! 292: /* FALLTHROUGH */
! 293:
! 294: case IBCS2_SIGNAL_MASK:
! 295: {
! 296: struct sys_sigaction_args sa_args;
! 297: struct sigaction *nbsa, *obsa, sa;
! 298:
! 299: nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
! 300: obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
! 301: SCARG(&sa_args, signum) = signum;
! 302: SCARG(&sa_args, nsa) = nbsa;
! 303: SCARG(&sa_args, osa) = obsa;
! 304:
! 305: sa.sa_handler = SCARG(uap, fp);
! 306: sigemptyset(&sa.sa_mask);
! 307: sa.sa_flags = 0;
! 308: #if 0
! 309: if (signum != SIGALRM)
! 310: sa.sa_flags = SA_RESTART;
! 311: #endif
! 312: if ((error = copyout(&sa, nbsa, sizeof(sa))) != 0)
! 313: return error;
! 314: if ((error = sys_sigaction(p, &sa_args, retval)) != 0) {
! 315: DPRINTF(("signal: sigaction failed: %d\n",
! 316: error));
! 317: *retval = (int)IBCS2_SIG_ERR;
! 318: return error;
! 319: }
! 320: if ((error = copyin(obsa, &sa, sizeof(sa))) != 0)
! 321: return error;
! 322: *retval = (int)sa.sa_handler;
! 323: return 0;
! 324: }
! 325:
! 326: case IBCS2_SIGHOLD_MASK:
! 327: {
! 328: struct sys_sigprocmask_args sa;
! 329:
! 330: SCARG(&sa, how) = SIG_BLOCK;
! 331: SCARG(&sa, mask) = sigmask(signum);
! 332: return sys_sigprocmask(p, &sa, retval);
! 333: }
! 334:
! 335: case IBCS2_SIGRELSE_MASK:
! 336: {
! 337: struct sys_sigprocmask_args sa;
! 338:
! 339: SCARG(&sa, how) = SIG_UNBLOCK;
! 340: SCARG(&sa, mask) = sigmask(signum);
! 341: return sys_sigprocmask(p, &sa, retval);
! 342: }
! 343:
! 344: case IBCS2_SIGIGNORE_MASK:
! 345: {
! 346: struct sys_sigaction_args sa_args;
! 347: struct sigaction *bsa, sa;
! 348:
! 349: bsa = stackgap_alloc(&sg, sizeof(struct sigaction));
! 350: SCARG(&sa_args, signum) = signum;
! 351: SCARG(&sa_args, nsa) = bsa;
! 352: SCARG(&sa_args, osa) = NULL;
! 353:
! 354: sa.sa_handler = SIG_IGN;
! 355: sigemptyset(&sa.sa_mask);
! 356: sa.sa_flags = 0;
! 357: if ((error = copyout(&sa, bsa, sizeof(sa))) != 0)
! 358: return error;
! 359: if ((error = sys_sigaction(p, &sa_args, retval)) != 0) {
! 360: DPRINTF(("sigignore: sigaction failed\n"));
! 361: return error;
! 362: }
! 363: return 0;
! 364: }
! 365:
! 366: case IBCS2_SIGPAUSE_MASK:
! 367: {
! 368: struct sys_sigsuspend_args sa;
! 369:
! 370: SCARG(&sa, mask) = p->p_sigmask &~ sigmask(signum);
! 371: return sys_sigsuspend(p, &sa, retval);
! 372: }
! 373:
! 374: default:
! 375: return ENOSYS;
! 376: }
! 377: }
! 378:
! 379: int
! 380: ibcs2_sys_sigprocmask(p, v, retval)
! 381: register struct proc *p;
! 382: void *v;
! 383: register_t *retval;
! 384: {
! 385: struct ibcs2_sys_sigprocmask_args /* {
! 386: syscallarg(int) how;
! 387: syscallarg(ibcs2_sigset_t *) set;
! 388: syscallarg(ibcs2_sigset_t *) oset;
! 389: } */ *uap = v;
! 390: ibcs2_sigset_t iss;
! 391: sigset_t bss;
! 392: int error = 0;
! 393:
! 394: if (SCARG(uap, oset) != NULL) {
! 395: /* Fix the return value first if needed */
! 396: bsd_to_ibcs2_sigset(&p->p_sigmask, &iss);
! 397: if ((error = copyout(&iss, SCARG(uap, oset), sizeof(iss))) != 0)
! 398: return error;
! 399: }
! 400:
! 401: if (SCARG(uap, set) == NULL)
! 402: /* Just examine */
! 403: return 0;
! 404:
! 405: if ((error = copyin(SCARG(uap, set), &iss, sizeof(iss))) != 0)
! 406: return error;
! 407:
! 408: ibcs2_to_bsd_sigset(&iss, &bss);
! 409:
! 410: (void) splhigh();
! 411:
! 412: switch (SCARG(uap, how)) {
! 413: case IBCS2_SIG_BLOCK:
! 414: p->p_sigmask |= bss & ~sigcantmask;
! 415: break;
! 416:
! 417: case IBCS2_SIG_UNBLOCK:
! 418: p->p_sigmask &= ~bss;
! 419: break;
! 420:
! 421: case IBCS2_SIG_SETMASK:
! 422: p->p_sigmask = bss & ~sigcantmask;
! 423: break;
! 424:
! 425: default:
! 426: error = EINVAL;
! 427: break;
! 428: }
! 429:
! 430: (void) spl0();
! 431:
! 432: return error;
! 433: }
! 434:
! 435: int
! 436: ibcs2_sys_sigpending(p, v, retval)
! 437: register struct proc *p;
! 438: void *v;
! 439: register_t *retval;
! 440: {
! 441: struct ibcs2_sys_sigpending_args /* {
! 442: syscallarg(ibcs2_sigset_t *) mask;
! 443: } */ *uap = v;
! 444: sigset_t bss;
! 445: ibcs2_sigset_t iss;
! 446:
! 447: bss = p->p_siglist & p->p_sigmask;
! 448: bsd_to_ibcs2_sigset(&bss, &iss);
! 449:
! 450: return copyout(&iss, SCARG(uap, mask), sizeof(iss));
! 451: }
! 452:
! 453: int
! 454: ibcs2_sys_sigsuspend(p, v, retval)
! 455: register struct proc *p;
! 456: void *v;
! 457: register_t *retval;
! 458: {
! 459: struct ibcs2_sys_sigsuspend_args /* {
! 460: syscallarg(ibcs2_sigset_t *) mask;
! 461: } */ *uap = v;
! 462: ibcs2_sigset_t sss;
! 463: sigset_t bss;
! 464: struct sys_sigsuspend_args sa;
! 465: int error;
! 466:
! 467: if ((error = copyin(SCARG(uap, mask), &sss, sizeof(sss))) != 0)
! 468: return error;
! 469:
! 470: ibcs2_to_bsd_sigset(&sss, &bss);
! 471:
! 472: SCARG(&sa, mask) = bss;
! 473: return sys_sigsuspend(p, &sa, retval);
! 474: }
! 475:
! 476: int
! 477: ibcs2_sys_pause(p, v, retval)
! 478: register struct proc *p;
! 479: void *v;
! 480: register_t *retval;
! 481: {
! 482: struct sys_sigsuspend_args bsa;
! 483:
! 484: SCARG(&bsa, mask) = p->p_sigmask;
! 485: return sys_sigsuspend(p, &bsa, retval);
! 486: }
! 487:
! 488: int
! 489: ibcs2_sys_kill(p, v, retval)
! 490: register struct proc *p;
! 491: void *v;
! 492: register_t *retval;
! 493: {
! 494: struct ibcs2_sys_kill_args /* {
! 495: syscallarg(int) pid;
! 496: syscallarg(int) signo;
! 497: } */ *uap = v;
! 498: struct sys_kill_args ka;
! 499:
! 500: if (SCARG(uap, signo) < 0 || SCARG(uap, signo) >= IBCS2_NSIG)
! 501: return (EINVAL);
! 502: SCARG(&ka, pid) = SCARG(uap, pid);
! 503: SCARG(&ka, signum) = ibcs2_to_bsd_sig[SCARG(uap, signo)];
! 504: return sys_kill(p, &ka, retval);
! 505: }
CVSweb