Annotation of MiNT/src/signal.c, revision 1.1

1.1     ! root        1: /*
        !             2: 
        !             3: Copyright 1990,1991,1992 Eric R. Smith. All rights reserved.
        !             4: 
        !             5: */
        !             6: 
        !             7: 
        !             8: 
        !             9: /* signal.c:: signal handling routines */
        !            10: 
        !            11: 
        !            12: 
        !            13: #include "mint.h"
        !            14: 
        !            15: 
        !            16: 
        !            17: void (*sig_routine)(); /* used in intr.s */
        !            18: 
        !            19: 
        !            20: 
        !            21: /*
        !            22: 
        !            23:  * killgroup(pgrp, sig): send a signal to all members of a process group
        !            24: 
        !            25:  * returns 0 on success, or an error code on failure
        !            26: 
        !            27:  */
        !            28: 
        !            29: 
        !            30: 
        !            31: long
        !            32: 
        !            33: killgroup(pgrp, sig)
        !            34: 
        !            35:        int pgrp, sig;
        !            36: 
        !            37: {
        !            38: 
        !            39:        PROC *p;
        !            40: 
        !            41:        int found = 0;
        !            42: 
        !            43: 
        !            44: 
        !            45:        TRACE("killgroup %d %d", pgrp, sig);
        !            46: 
        !            47: 
        !            48: 
        !            49:        if (pgrp < 0)
        !            50: 
        !            51:                return EINTRN;
        !            52: 
        !            53: 
        !            54: 
        !            55:        for (p = proclist; p; p = p->gl_next) {
        !            56: 
        !            57:                if (p->pgrp == pgrp) {
        !            58: 
        !            59:                        post_sig(p, sig);
        !            60: 
        !            61:                        found++;
        !            62: 
        !            63:                }
        !            64: 
        !            65:        }
        !            66: 
        !            67:        if (found) {
        !            68: 
        !            69:                check_sigs();   /* see if the current process is affected */
        !            70: 
        !            71:                return 0;
        !            72: 
        !            73:        }
        !            74: 
        !            75:        else {
        !            76: 
        !            77:                DEBUG("killgroup: no processes found");
        !            78: 
        !            79:                return EFILNF;
        !            80: 
        !            81:        }
        !            82: 
        !            83: }
        !            84: 
        !            85: 
        !            86: 
        !            87: /* post_sig: post a signal as being pending. It is assumed that the
        !            88: 
        !            89:    caller has already verified that "sig" is a valid signal, and
        !            90: 
        !            91:    moreover it is the caller's responsibility to call check_sigs()
        !            92: 
        !            93:    if it's possible that p == curproc
        !            94: 
        !            95:  */
        !            96: 
        !            97: 
        !            98: 
        !            99: void
        !           100: 
        !           101: post_sig(p, sig)
        !           102: 
        !           103:        PROC *p;
        !           104: 
        !           105:        int sig;
        !           106: 
        !           107: {
        !           108: 
        !           109:        ulong sigm;
        !           110: 
        !           111: 
        !           112: 
        !           113: /* if process is ignoring this signal, do nothing
        !           114: 
        !           115:  * also: signal 0 is SIGNULL, and should never be delivered through
        !           116: 
        !           117:  * the normal channels (indeed, it's filtered out in dossig.c,
        !           118: 
        !           119:  * but the extra sanity check here is harmless). The kernel uses
        !           120: 
        !           121:  * signal 0 internally for some purposes, but it is handled
        !           122: 
        !           123:  * specially (see supexec() in xbios.c, for example).
        !           124: 
        !           125:  */
        !           126: 
        !           127:        if (p->sighandle[sig] == SIG_IGN || sig == 0)
        !           128: 
        !           129:                return;
        !           130: 
        !           131: 
        !           132: 
        !           133: /* if the process is already dead, do nothing */
        !           134: 
        !           135:        if (p->wait_q == ZOMBIE_Q || p->wait_q == TSR_Q)
        !           136: 
        !           137:                return;
        !           138: 
        !           139: 
        !           140: 
        !           141: /* mark the signal as pending */
        !           142: 
        !           143:        sigm = (1L << (unsigned long)sig);
        !           144: 
        !           145:        p->sigpending |= sigm;
        !           146: 
        !           147: 
        !           148: 
        !           149: /* if the signal is masked, do nothing further */
        !           150: 
        !           151:        if ( (p->sigmask & sigm) != 0 )
        !           152: 
        !           153:                return;
        !           154: 
        !           155: 
        !           156: 
        !           157: /* otherwise, make sure the process is awake */
        !           158: 
        !           159:        if (p->wait_q && p->wait_q != READY_Q) {
        !           160: 
        !           161:                rm_q(p->wait_q, p);
        !           162: 
        !           163:                add_q(READY_Q, p);
        !           164: 
        !           165:        }
        !           166: 
        !           167: }
        !           168: 
        !           169: 
        !           170: 
        !           171: /*
        !           172: 
        !           173:  * check_sigs: see if we have any signals pending. if so,
        !           174: 
        !           175:  * handle them.
        !           176: 
        !           177:  */
        !           178: 
        !           179: 
        !           180: 
        !           181: void
        !           182: 
        !           183: check_sigs()
        !           184: 
        !           185: {
        !           186: 
        !           187:        ulong sigs, sigm;
        !           188: 
        !           189:        ulong i;
        !           190: 
        !           191: 
        !           192: 
        !           193:        if (curproc->pid == 0) return;
        !           194: 
        !           195:        sigs = curproc->sigpending & ~(curproc->sigmask);
        !           196: 
        !           197:        if (sigs) {
        !           198: 
        !           199:                sigm = 2;
        !           200: 
        !           201:                for (i = 1; i < NSIG; i++) {
        !           202: 
        !           203:                        if (sigs & sigm) {
        !           204: 
        !           205:                                ulong omask;
        !           206: 
        !           207: 
        !           208: 
        !           209:                                curproc->sigpending &= ~sigm;
        !           210: 
        !           211:                                omask = curproc->sigmask;
        !           212: 
        !           213: 
        !           214: 
        !           215: /* sigextra gives which extra signals should also be masked */
        !           216: 
        !           217:                                curproc->sigmask |= curproc->sigextra[i] | sigm;
        !           218: 
        !           219:                                handle_sig(i);
        !           220: 
        !           221: 
        !           222: 
        !           223: /*
        !           224: 
        !           225:  * POSIX.1-3.3.4.2(723) "If and when the user's signal handler returns
        !           226: 
        !           227:  * normally, the original signal mask is restored."
        !           228: 
        !           229:  *
        !           230: 
        !           231:  * BUG?: This unmasking could unmask a pending signal which we will not
        !           232: 
        !           233:  * see this time around (if the signal number is less than i) and which
        !           234: 
        !           235:  * was not pending when we started; should we detect this condition and
        !           236: 
        !           237:  * loop around for a second try? POSIX only guarantees delivery of
        !           238: 
        !           239:  * one signal per kernel entry, so this shouldn't really be a problem.
        !           240: 
        !           241:  */
        !           242: 
        !           243:                                curproc->sigmask = omask;       /* unmask signals */
        !           244: 
        !           245:                        }
        !           246: 
        !           247:                        sigm = sigm << 1;
        !           248: 
        !           249:                }
        !           250: 
        !           251:        }
        !           252: 
        !           253: }
        !           254: 
        !           255: 
        !           256: 
        !           257: /*
        !           258: 
        !           259:  * raise: cause a signal to be raised in the current process
        !           260: 
        !           261:  */
        !           262: 
        !           263: 
        !           264: 
        !           265: void
        !           266: 
        !           267: raise(sig)
        !           268: 
        !           269:        int sig;
        !           270: 
        !           271: {
        !           272: 
        !           273:        post_sig(curproc, sig);
        !           274: 
        !           275:        check_sigs();
        !           276: 
        !           277: }
        !           278: 
        !           279: 
        !           280: 
        !           281: #ifdef EXCEPTION_SIGS
        !           282: 
        !           283: /* exception numbers corresponding to signals */
        !           284: 
        !           285: char excep_num[NSIG] =
        !           286: 
        !           287: { 0, 0, 0, 0,
        !           288: 
        !           289:   4,                   /* SIGILL == illegal instruction */
        !           290: 
        !           291:   9,                   /* SIGTRAP == trace trap        */
        !           292: 
        !           293:   4,                   /* pretend SIGABRT is also illegal instruction */
        !           294: 
        !           295:   8,                   /* SIGPRIV == privileged instruction exception */
        !           296: 
        !           297:   5,                   /* SIGFPE == divide by zero */
        !           298: 
        !           299:   0, 2,                        /* SIGBUS == bus error */
        !           300: 
        !           301:   3                    /* SIGSEGV == address error */
        !           302: 
        !           303: /* everything else gets zeros */
        !           304: 
        !           305: };
        !           306: 
        !           307: 
        !           308: 
        !           309: /* a "0" means we don't print a message when it happens -- typically the
        !           310: 
        !           311:    user is expecting a synchronous signal, so we don't need to report it
        !           312: 
        !           313: */
        !           314: 
        !           315: 
        !           316: 
        !           317: const char *signames[NSIG] = { 0,
        !           318: 
        !           319: 0, 0, 0, "ILLEGAL INSTRUCTION", "TRACE TRAP",
        !           320: 
        !           321: 0, "PRIVILEGE VIOLATION", "DIVISION BY ZERO", 0, "BUS ERROR",
        !           322: 
        !           323: "ADDRESS ERROR", "BAD SYSTEM CALL", 0, 0, 0,
        !           324: 
        !           325: 0, 0, 0, 0, 0,
        !           326: 
        !           327: 0, 0, 0, "CPU TIME EXHAUSTED", "FILE TOO BIG",
        !           328: 
        !           329: 0, 0, 0, 0, 0
        !           330: 
        !           331: };
        !           332: 
        !           333: 
        !           334: 
        !           335: /*
        !           336: 
        !           337:  * replaces the TOS "show bombs" routine: for now, print the name of the
        !           338: 
        !           339:  * interrupt on the console, and save info on the crash in the appropriate
        !           340: 
        !           341:  * system area
        !           342: 
        !           343:  */
        !           344: 
        !           345: 
        !           346: 
        !           347: void
        !           348: 
        !           349: bombs(sig)
        !           350: 
        !           351:        int sig;
        !           352: 
        !           353: {
        !           354: 
        !           355:        long *procinfo = (long *)0x380L;
        !           356: 
        !           357:        int i;
        !           358: 
        !           359:        CONTEXT *crash;
        !           360: 
        !           361: 
        !           362: 
        !           363:        if (signames[sig]) {
        !           364: 
        !           365:                ALERT("%s: User PC=%lx (basepage=%lx)",
        !           366: 
        !           367:                        signames[sig],
        !           368: 
        !           369:                        curproc->ctxt[SYSCALL].pc, curproc->base);
        !           370: 
        !           371: 
        !           372: 
        !           373: /* save the processor state at crash time */
        !           374: 
        !           375: /* assumes that "crash time" is the context curproc->ctxt[SYSCALL] */
        !           376: 
        !           377: /* BUG: this is not true if the crash happened in the kernel; in the
        !           378: 
        !           379:  * latter case, the crash context wasn't saved anywhere.
        !           380: 
        !           381:  */
        !           382: 
        !           383:                crash = &curproc->ctxt[SYSCALL];
        !           384: 
        !           385:                *procinfo++ = 0x12345678;       /* magic flag for valid info */
        !           386: 
        !           387:                for (i = 0; i < 15; i++)
        !           388: 
        !           389:                        *procinfo++ = crash->regs[i];
        !           390: 
        !           391:                *procinfo++ = crash->ssp;
        !           392: 
        !           393:                *procinfo++ = ((long)excep_num[sig]) << 24L;
        !           394: 
        !           395:                *procinfo++ = crash->usp;
        !           396: 
        !           397: 
        !           398: 
        !           399: /* we're also supposed to save some info from the supervisor stack. it's not
        !           400: 
        !           401:  * clear what we should do for MiNT, since most of the stuff that used to be
        !           402: 
        !           403:  * on the stack has been put in the CONTXT struct. Moreover, we don't want
        !           404: 
        !           405:  * to crash because of an attempt to access illegal memory. Hence, we do
        !           406: 
        !           407:  * nothing here...
        !           408: 
        !           409:  */
        !           410: 
        !           411:        }
        !           412: 
        !           413: }
        !           414: 
        !           415: #endif
        !           416: 
        !           417: 
        !           418: 
        !           419: /*
        !           420: 
        !           421:  * handle_sig: do whatever is appropriate to handle a signal
        !           422: 
        !           423:  */
        !           424: 
        !           425: 
        !           426: 
        !           427: static long unwound_stack = 0;
        !           428: 
        !           429: 
        !           430: 
        !           431: void
        !           432: 
        !           433: handle_sig(sig)
        !           434: 
        !           435:        int sig;
        !           436: 
        !           437: {
        !           438: 
        !           439:        long oldstack, newstack;
        !           440: 
        !           441:        long *stack;
        !           442: 
        !           443:        CONTEXT *call, oldsysctxt, newcurrent;
        !           444: 
        !           445:        extern void sig_return();
        !           446: 
        !           447: 
        !           448: 
        !           449:        if (curproc->sighandle[sig] == SIG_IGN)
        !           450: 
        !           451:                return;
        !           452: 
        !           453:        else if (curproc->sighandle[sig] == SIG_DFL) {
        !           454: 
        !           455: _default:
        !           456: 
        !           457:                switch(sig) {
        !           458: 
        !           459: #if 0
        !           460: 
        !           461: /* Note: SIGNULL is filtered out in dossig.c and is never actually
        !           462: 
        !           463:  * delivered (its only purpose for the user is to test for the existence of
        !           464: 
        !           465:  * a process, it isn't a real signal). The kernel uses SIGNULL
        !           466: 
        !           467:  * internally, but all such code does the signal handling "by hand"
        !           468: 
        !           469:  * and so no default handling is necessary.
        !           470: 
        !           471:  */
        !           472: 
        !           473:                        case SIGNULL:
        !           474: 
        !           475: #endif
        !           476: 
        !           477:                        case SIGWINCH:
        !           478: 
        !           479:                        case SIGCHLD:
        !           480: 
        !           481:                                return;         /* do nothing */
        !           482: 
        !           483:                        case SIGSTOP:
        !           484: 
        !           485:                        case SIGTSTP:
        !           486: 
        !           487:                        case SIGTTIN:
        !           488: 
        !           489:                        case SIGTTOU:
        !           490: 
        !           491:                                stop(sig);
        !           492: 
        !           493:                                return;
        !           494: 
        !           495:                        case SIGCONT:
        !           496: 
        !           497:                                curproc->sigpending &= ~STOPSIGS;
        !           498: 
        !           499:                                return;
        !           500: 
        !           501: 
        !           502: 
        !           503: /* here are the fatal signals. for SIGINT, we use p_term() so that
        !           504: 
        !           505:  * TOS programs that catch ^C via the vector at 0x400 will work. for
        !           506: 
        !           507:  * other signals (especially SIGKILL) we don't want that to happen;
        !           508: 
        !           509:  * TOS programs aren't prepared to deal with signals.
        !           510: 
        !           511:  */
        !           512: 
        !           513:                        case SIGINT:            /* ^C */
        !           514: 
        !           515:                                if (curproc->domain == DOM_TOS) {
        !           516: 
        !           517:                                        curproc->sigmask &= ~(1L<<SIGINT);
        !           518: 
        !           519:                                        p_term(-32);
        !           520: 
        !           521:                                        return;
        !           522: 
        !           523:                                }
        !           524: 
        !           525:                                /* otherwise, fall through */
        !           526: 
        !           527:                        default:
        !           528: 
        !           529: #ifdef EXCEPTION_SIGS
        !           530: 
        !           531:                                bombs(sig); /* tell the user what happened */
        !           532: 
        !           533: #endif
        !           534: 
        !           535:                                terminate(sig << 8, ZOMBIE_Q);
        !           536: 
        !           537:                }
        !           538: 
        !           539:        }
        !           540: 
        !           541:        else {          /* user wants to handle it himself */
        !           542: 
        !           543: 
        !           544: 
        !           545: /* another kludge: there is one case in which the p_sigreturn mechanism
        !           546: 
        !           547:  * is invoked by the kernel, namely when the user calls Supexec()
        !           548: 
        !           549:  * or when s/he installs a handler for the GEMDOS terminate vector (#0x102)
        !           550: 
        !           551:  * and the program terminates. MiNT fakes the call to user code with
        !           552: 
        !           553:  * signal 0 (SIGNULL); programs that longjmp out of the user function
        !           554: 
        !           555:  * and are later sent back to it again (e.g. if ^C keeps getting pressed
        !           556: 
        !           557:  * and a terminate vector has been installed) will grow the stack without
        !           558: 
        !           559:  * bound unless we watch for this case.
        !           560: 
        !           561:  *
        !           562: 
        !           563:  * Solution (sort of): whenever Pterm() is called, we unwind the
        !           564: 
        !           565:  * stack; otherwise, we let it grow, so that nested Supexec()
        !           566: 
        !           567:  * calls work.
        !           568: 
        !           569:  *
        !           570: 
        !           571:  * Note that SIGNULL is thrown away when sent by user processes, 
        !           572: 
        !           573:  * and the user can't mask it (it's UNMASKABLE), so there is
        !           574: 
        !           575:  * is no possibility of confusion with anything the user does.
        !           576: 
        !           577:  */
        !           578: 
        !           579:                if (sig == 0) {
        !           580: 
        !           581:        /* p_term() sets sigmask to let us know to do Psigreturn */
        !           582: 
        !           583:                        if (curproc->sigmask & 1L) {
        !           584: 
        !           585:                                p_sigreturn();
        !           586: 
        !           587:                                curproc->sigmask &= ~1L;
        !           588: 
        !           589:                        } else {
        !           590: 
        !           591:                                unwound_stack = 0;
        !           592: 
        !           593:                        }
        !           594: 
        !           595:                }
        !           596: 
        !           597: 
        !           598: 
        !           599:                call = &curproc->ctxt[SYSCALL];
        !           600: 
        !           601: /*
        !           602: 
        !           603:  * what we do is build two fake stack frames; the bottom one is
        !           604: 
        !           605:  * for a call to the user function, with (long)parameter being the
        !           606: 
        !           607:  * signal number; the top one is for sig_return.
        !           608: 
        !           609:  * When the user function returns, it returns to sig_return, which
        !           610: 
        !           611:  * calls into the kernel to restore the context in prev_ctxt
        !           612: 
        !           613:  * (thus putting us back here). We can then continue on our way.
        !           614: 
        !           615:  */
        !           616: 
        !           617: 
        !           618: 
        !           619: /* set a new system stack, with a bit of buffer space */
        !           620: 
        !           621:                oldstack = curproc->sysstack;
        !           622: 
        !           623:                newstack = ((long) ( (&newcurrent) - 3 )) - 12;
        !           624: 
        !           625: 
        !           626: 
        !           627:                if (newstack < (long)curproc->stack + ISTKSIZE + 256) {
        !           628: 
        !           629:                        ALERT("stack overflow");
        !           630: 
        !           631:                        goto _default;
        !           632: 
        !           633:                }
        !           634: 
        !           635:                else if ((long) curproc->stack + STKSIZE < newstack) {
        !           636: 
        !           637:                        FATAL("system stack not in proc structure");
        !           638: 
        !           639:                }
        !           640: 
        !           641: 
        !           642: 
        !           643: /* unwound_stack is set by p_sigreturn() */
        !           644: 
        !           645:                if (sig == 0 && unwound_stack)
        !           646: 
        !           647:                        curproc->sysstack = unwound_stack;
        !           648: 
        !           649:                else
        !           650: 
        !           651:                        curproc->sysstack = newstack;
        !           652: 
        !           653:                oldsysctxt = *call;
        !           654: 
        !           655:                stack = (long *)(call->sr & 0x2000 ? call->ssp :
        !           656: 
        !           657:                                call->usp);
        !           658: 
        !           659: /*
        !           660: 
        !           661:    Hmmm... here's another potential problem for the signal 0 terminate
        !           662: 
        !           663:    vector: if the program keeps returning back to user mode without
        !           664: 
        !           665:    worrying about the supervisor stack, we'll eventually overflow it.
        !           666: 
        !           667:    However, if the program is in supervisor mode itself, then we don't
        !           668: 
        !           669:    want to stomp on its stack. Temporary solution: ignore the problem,
        !           670: 
        !           671:    the stack's only growing 8 bytes at a time.
        !           672: 
        !           673:  */
        !           674: 
        !           675:                *(--stack) = (long)sig;
        !           676: 
        !           677:                *(--stack) = (long)sig_return;
        !           678: 
        !           679:                if (call->sr & 0x2000)
        !           680: 
        !           681:                        call->ssp = ((long) stack);
        !           682: 
        !           683:                else
        !           684: 
        !           685:                        call->usp = ((long) stack);
        !           686: 
        !           687:                call->pc = (long) curproc->sighandle[sig];
        !           688: 
        !           689: 
        !           690: 
        !           691:                ((long *)curproc->sysstack)[1] = FRAME_MAGIC;
        !           692: 
        !           693:                ((long *)curproc->sysstack)[2] = oldstack;
        !           694: 
        !           695:                ((long *)curproc->sysstack)[3] = sig;
        !           696: 
        !           697: 
        !           698: 
        !           699:                if (save_context(&newcurrent) == 0 ) {
        !           700: 
        !           701: /*
        !           702: 
        !           703:  * go do the signal; eventually, we'll restore this context (unless the
        !           704: 
        !           705:  * user longjmp'd out of his signal handler). while the user is handling
        !           706: 
        !           707:  * the signal, it's masked out to prevent race conditions. p_sigreturn()
        !           708: 
        !           709:  * will unmask it for us when the user is finished.
        !           710: 
        !           711:  */
        !           712: 
        !           713:                        newcurrent.regs[0] = CTXT_MAGIC;
        !           714: 
        !           715:                                /* set D0 so next return is different */
        !           716: 
        !           717:                        assert(curproc->magic == CTXT_MAGIC);
        !           718: 
        !           719:                        leave_kernel();
        !           720: 
        !           721:                        restore_context(call);
        !           722: 
        !           723:                }
        !           724: 
        !           725: /*
        !           726: 
        !           727:  * OK, we get here from p_sigreturn, via the user returning from
        !           728: 
        !           729:  * the handler to sig_return. Restoring the stack and unmasking the
        !           730: 
        !           731:  * signal have been done already for us by p_sigreturn.
        !           732: 
        !           733:  * We should just restore the old system call context
        !           734: 
        !           735:  * and continue with whatever it was we were doing.
        !           736: 
        !           737:  */
        !           738: 
        !           739:                TRACE("done handling signal");
        !           740: 
        !           741:                curproc->ctxt[SYSCALL] = oldsysctxt;
        !           742: 
        !           743:                assert(curproc->magic == CTXT_MAGIC);
        !           744: 
        !           745:        }
        !           746: 
        !           747: }
        !           748: 
        !           749: 
        !           750: 
        !           751: /*
        !           752: 
        !           753:  * the p_sigreturn system call
        !           754: 
        !           755:  * When called by the user from inside a signal handler, it indicates a
        !           756: 
        !           757:  * desire to restore the old stack frame prior to a longjmp() out of
        !           758: 
        !           759:  * the handler.
        !           760: 
        !           761:  * When called from the sig_return module, it indicates that the user
        !           762: 
        !           763:  * is finished a handler, and we should not only restore the stack
        !           764: 
        !           765:  * frame but also the old context we were working in (which is on the
        !           766: 
        !           767:  * system call stack -- see handle_sig).
        !           768: 
        !           769:  * The "valid_return" variable is 0 in the first case, 1 in the second.
        !           770: 
        !           771:  */
        !           772: 
        !           773: 
        !           774: 
        !           775: short valid_return;
        !           776: 
        !           777: 
        !           778: 
        !           779: long
        !           780: 
        !           781: p_sigreturn()
        !           782: 
        !           783: {
        !           784: 
        !           785:        CONTEXT *oldctxt;
        !           786: 
        !           787:        long *frame;
        !           788: 
        !           789:        long sig;
        !           790: 
        !           791: 
        !           792: 
        !           793:        unwound_stack = 0;
        !           794: 
        !           795: top:
        !           796: 
        !           797:        frame = (long *)curproc->sysstack;
        !           798: 
        !           799:        frame++;        /* frame should point at FRAME_MAGIC, now */
        !           800: 
        !           801:        sig = frame[2];
        !           802: 
        !           803:        if (*frame != FRAME_MAGIC || (sig < 0) || (sig >= NSIG)) {
        !           804: 
        !           805:                FATAL("Psigreturn: system stack corrupted");
        !           806: 
        !           807:        }
        !           808: 
        !           809:        if (frame[1] == 0) {
        !           810: 
        !           811:                DEBUG("Psigreturn: frame at %lx points to 0", frame-1);
        !           812: 
        !           813:                return 0;
        !           814: 
        !           815:        }
        !           816: 
        !           817:        unwound_stack = curproc->sysstack;
        !           818: 
        !           819:        TRACE("Psigreturn(%d)", (int)sig);
        !           820: 
        !           821: 
        !           822: 
        !           823:        curproc->sysstack = frame[1];   /* restore frame */
        !           824: 
        !           825:        curproc->sigmask &= ~(1L<<sig); /* unblock signal */
        !           826: 
        !           827: 
        !           828: 
        !           829:        if (!valid_return) {
        !           830: 
        !           831: /* here, the user is telling us that a longjmp out of a signal handler is
        !           832: 
        !           833:  * about to occur; so we should unwind *all* the signal frames
        !           834: 
        !           835:  */
        !           836: 
        !           837:                goto top;
        !           838: 
        !           839:        }
        !           840: 
        !           841:        else {
        !           842: 
        !           843:                valid_return = 0;
        !           844: 
        !           845:                oldctxt = ((CONTEXT *)(&frame[2])) + 3;
        !           846: 
        !           847:                if (oldctxt->regs[0] != CTXT_MAGIC) {
        !           848: 
        !           849:                        FATAL("p_sigreturn: corrupted context");
        !           850: 
        !           851:                }
        !           852: 
        !           853:                assert(curproc->magic == CTXT_MAGIC);
        !           854: 
        !           855:                restore_context(oldctxt);
        !           856: 
        !           857:                return 0;       /* dummy -- this isn't reached */
        !           858: 
        !           859:        }
        !           860: 
        !           861: }
        !           862: 
        !           863: 
        !           864: 
        !           865: /*
        !           866: 
        !           867:  * stop a process because of signal "sig"
        !           868: 
        !           869:  */
        !           870: 
        !           871: 
        !           872: 
        !           873: void
        !           874: 
        !           875: stop(sig)
        !           876: 
        !           877:        int sig;
        !           878: 
        !           879: {
        !           880: 
        !           881:        unsigned int code;
        !           882: 
        !           883:        unsigned long oldmask;
        !           884: 
        !           885:        PROC *p;
        !           886: 
        !           887: 
        !           888: 
        !           889:        code = sig << 8;
        !           890: 
        !           891: 
        !           892: 
        !           893:        if (curproc->pid == 0) {
        !           894: 
        !           895:                ALERT("attempt to stop MiNT");
        !           896: 
        !           897:                return;
        !           898: 
        !           899:        }
        !           900: 
        !           901: 
        !           902: 
        !           903: /* notify parent */
        !           904: 
        !           905:        p = pid2proc(curproc->ppid);
        !           906: 
        !           907:        if (p && !(p->sigflags[SIGCHLD] & SA_NOCLDSTOP)) {
        !           908: 
        !           909:                post_sig(p, SIGCHLD);
        !           910: 
        !           911:        }
        !           912: 
        !           913: 
        !           914: 
        !           915:        oldmask = curproc->sigmask;
        !           916: 
        !           917: 
        !           918: 
        !           919: /* mask out most signals */
        !           920: 
        !           921:        curproc->sigmask |= ~(UNMASKABLE | SIGTERM);
        !           922: 
        !           923: 
        !           924: 
        !           925: /* sleep until someone signals us awake */
        !           926: 
        !           927:        sleep(STOP_Q, (long) code | 0177);
        !           928: 
        !           929: 
        !           930: 
        !           931: /* when we wake up, restore the signal mask */
        !           932: 
        !           933:        curproc->sigmask = oldmask;
        !           934: 
        !           935: 
        !           936: 
        !           937: /* and discard any signals that would cause us to stop again */
        !           938: 
        !           939:        curproc->sigpending &= ~STOPSIGS;
        !           940: 
        !           941: }
        !           942: 
        !           943: 
        !           944: 
        !           945: /*
        !           946: 
        !           947:  * interrupt handlers to raise SIGBUS, SIGSEGV, etc. Note that for
        !           948: 
        !           949:  * really fatal errors we reset the handler to SIG_DFL, so that
        !           950: 
        !           951:  * a second such error kills us
        !           952: 
        !           953:  */
        !           954: 
        !           955: 
        !           956: 
        !           957: void
        !           958: 
        !           959: exception(sig)
        !           960: 
        !           961:        int sig;
        !           962: 
        !           963: {
        !           964: 
        !           965:        curproc->sighandle[sig] = SIG_DFL;
        !           966: 
        !           967:        raise(sig);
        !           968: 
        !           969: }
        !           970: 
        !           971: 
        !           972: 
        !           973: void
        !           974: 
        !           975: sigbus()
        !           976: 
        !           977: {
        !           978: 
        !           979:        exception(SIGBUS);
        !           980: 
        !           981: }
        !           982: 
        !           983: 
        !           984: 
        !           985: void
        !           986: 
        !           987: sigaddr()
        !           988: 
        !           989: {
        !           990: 
        !           991:        exception(SIGSEGV);
        !           992: 
        !           993: }
        !           994: 
        !           995: 
        !           996: 
        !           997: void
        !           998: 
        !           999: sigill()
        !          1000: 
        !          1001: {
        !          1002: 
        !          1003:        exception(SIGILL);
        !          1004: 
        !          1005: }
        !          1006: 
        !          1007: 
        !          1008: 
        !          1009: void
        !          1010: 
        !          1011: sigpriv()
        !          1012: 
        !          1013: {
        !          1014: 
        !          1015:        raise(SIGPRIV);
        !          1016: 
        !          1017: }
        !          1018: 
        !          1019: 
        !          1020: 
        !          1021: void
        !          1022: 
        !          1023: sigfpe()
        !          1024: 
        !          1025: {
        !          1026: 
        !          1027:        raise(SIGFPE);
        !          1028: 
        !          1029: }
        !          1030: 
        !          1031: 
        !          1032: 
        !          1033: void
        !          1034: 
        !          1035: sigtrap()
        !          1036: 
        !          1037: {
        !          1038: 
        !          1039:        raise(SIGTRAP);
        !          1040: 
        !          1041: }
        !          1042: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.