Annotation of MiNT/src/dossig.c, revision 1.1.1.4

1.1       root        1: /*
                      2: 
1.1.1.4 ! root        3: Copyright 1990,1991,1992,1994 Eric R. Smith.
1.1.1.3   root        4: 
                      5: All rights reserved.
1.1       root        6: 
                      7: */
                      8: 
                      9: 
                     10: 
                     11: /* dossig.c:: dos signal handling routines */
                     12: 
                     13: 
                     14: 
                     15: #include "mint.h"
                     16: 
                     17: 
                     18: 
1.1.1.4 ! root       19: void ARGS_ON_STACK sig_user P_((int vec));
        !            20: 
        !            21: 
        !            22: 
1.1       root       23: /*
                     24: 
                     25:  * send a signal to another process. If pid > 0, send the signal just to
                     26: 
                     27:  * that process. If pid < 0, send the signal to all processes whose process
                     28: 
                     29:  * group is -pid. If pid == 0, send the signal to all processes with the
                     30: 
                     31:  * same process group id.
                     32: 
                     33:  *
                     34: 
                     35:  * note: post_sig just posts the signal to the process.
                     36: 
                     37:  */
                     38: 
                     39: 
                     40: 
1.1.1.2   root       41: long ARGS_ON_STACK
1.1       root       42: 
                     43: p_kill(pid, sig)
                     44: 
                     45:        int pid, sig;
                     46: 
                     47: {
                     48: 
                     49:        PROC *p;
                     50: 
1.1.1.4 ! root       51:        long r;
        !            52: 
1.1       root       53: 
                     54: 
1.1.1.2   root       55:        TRACE(("Pkill(%d, %d)", pid, sig));
1.1       root       56: 
                     57:        if (sig < 0 || sig >= NSIG) {
                     58: 
1.1.1.2   root       59:                DEBUG(("Pkill: signal out of range"));
1.1       root       60: 
                     61:                return ERANGE;
                     62: 
                     63:        }
                     64: 
                     65: 
                     66: 
                     67:        if (pid < 0)
                     68: 
1.1.1.4 ! root       69:                r = killgroup(-pid, sig, 0);
1.1       root       70: 
                     71:        else if (pid == 0)
                     72: 
1.1.1.4 ! root       73:                r = killgroup(curproc->pgrp, sig, 0);
1.1       root       74: 
                     75:        else {
                     76: 
                     77:                p = pid2proc(pid);
                     78: 
                     79:                if (p == 0 || p->wait_q == ZOMBIE_Q || p->wait_q == TSR_Q) {
                     80: 
1.1.1.2   root       81:                        DEBUG(("Pkill: pid %d not found", pid));
1.1       root       82: 
                     83:                        return EFILNF;
                     84: 
                     85:                }
                     86: 
                     87:                if (curproc->euid && curproc->ruid != p->ruid) {
                     88: 
1.1.1.2   root       89:                        DEBUG(("Pkill: wrong user"));
1.1       root       90: 
                     91:                        return EACCDN;
                     92: 
                     93:                }
                     94: 
                     95: 
                     96: 
                     97: /* if the user sends signal 0, don't deliver it -- for users, signal
                     98: 
                     99:  * 0 is a null signal used to test the existence of a process
                    100: 
                    101:  */
                    102: 
                    103:                if (sig != 0)
                    104: 
                    105:                        post_sig(p, sig);
                    106: 
1.1.1.4 ! root      107:                r = 0;
        !           108: 
1.1       root      109:        }
                    110: 
                    111: 
                    112: 
1.1.1.4 ! root      113:        if (r == 0) {
1.1       root      114: 
1.1.1.4 ! root      115:                check_sigs();
1.1       root      116: 
1.1.1.4 ! root      117:                TRACE(("Pkill: returning OK"));
        !           118: 
        !           119:        }
        !           120: 
        !           121:        return r;
1.1       root      122: 
                    123: }
                    124: 
                    125: 
                    126: 
                    127: /*
                    128: 
                    129:  * set a user-specified signal handler, POSIX.1 style
                    130: 
                    131:  * "oact", if non-null, gets the old signal handling
                    132: 
                    133:  * behaviour; "act", if non-null, specifies new
                    134: 
                    135:  * behaviour
                    136: 
                    137:  */
                    138: 
                    139: 
                    140: 
1.1.1.2   root      141: long ARGS_ON_STACK
1.1       root      142: 
                    143: p_sigaction(sig, act, oact)
                    144: 
                    145:        int sig;
                    146: 
                    147:        const struct sigaction *act;
                    148: 
                    149:        struct sigaction *oact;
                    150: 
                    151: {
                    152: 
1.1.1.2   root      153:        TRACE(("Psigaction(%d)", sig));
1.1       root      154: 
                    155:        if (sig < 1 || sig >= NSIG)
                    156: 
                    157:                return ERANGE;
                    158: 
                    159:        if (act && (sig == SIGKILL || sig == SIGSTOP))
                    160: 
                    161:                return EACCDN;
                    162: 
                    163:        if (oact) {
                    164: 
                    165:                oact->sa_handler = curproc->sighandle[sig];
                    166: 
                    167:                oact->sa_mask = curproc->sigextra[sig];
                    168: 
1.1.1.2   root      169:                oact->sa_flags = curproc->sigflags[sig] & SAUSER;
1.1       root      170: 
                    171:        }
                    172: 
                    173:        if (act) {
                    174: 
1.1.1.2   root      175:                ushort flags;
                    176: 
                    177: 
                    178: 
1.1       root      179:                curproc->sighandle[sig] = act->sa_handler;
                    180: 
                    181:                curproc->sigextra[sig] = act->sa_mask & ~UNMASKABLE;
                    182: 
1.1.1.2   root      183: 
                    184: 
                    185: /* only the flags in SAUSER can be changed by the user */
                    186: 
                    187:                flags = curproc->sigflags[sig] & ~SAUSER;
                    188: 
                    189:                flags |= act->sa_flags & SAUSER;
                    190: 
                    191:                curproc->sigflags[sig] = flags;
1.1       root      192: 
                    193:  
                    194: 
                    195: /* various special things that should happen */
                    196: 
                    197:                if (act->sa_handler == SIG_IGN) {
                    198: 
                    199:                        /* discard pending signals */
                    200: 
                    201:                        curproc->sigpending &= ~(1L<<sig);
                    202: 
                    203:                }
                    204: 
                    205: 
                    206: 
                    207: /* I dunno if this is right, but bash seems to expect it */
                    208: 
                    209:                curproc->sigmask &= ~(1L<<sig);
                    210: 
                    211:        }
                    212: 
                    213:        return 0;
                    214: 
                    215: }
                    216: 
                    217: 
                    218: 
                    219: /*
                    220: 
                    221:  * set a user-specified signal handler
                    222: 
                    223:  */
                    224: 
                    225: 
                    226: 
1.1.1.2   root      227: long ARGS_ON_STACK
1.1       root      228: 
                    229: p_signal(sig, handler)
                    230: 
                    231:        int sig;
                    232: 
                    233:        long handler;
                    234: 
                    235: {
                    236: 
                    237:        long oldhandle;
                    238: 
                    239: 
                    240: 
1.1.1.2   root      241:        TRACE(("Psignal(%d, %lx)", sig, handler));
1.1       root      242: 
                    243:        if (sig < 1 || sig >= NSIG)
                    244: 
                    245:                return ERANGE;
                    246: 
                    247:        if (sig == SIGKILL || sig == SIGSTOP)
                    248: 
                    249:                return EACCDN;
                    250: 
                    251:        oldhandle = curproc->sighandle[sig];
                    252: 
                    253:        curproc->sighandle[sig] = handler;
                    254: 
                    255:        curproc->sigextra[sig] = 0;
                    256: 
                    257:        curproc->sigflags[sig] = 0;
                    258: 
                    259: 
                    260: 
                    261: /* various special things that should happen */
                    262: 
                    263:        if (handler == SIG_IGN) {
                    264: 
                    265:                /* discard pending signals */
                    266: 
                    267:                curproc->sigpending &= ~(1L<<sig);
                    268: 
                    269:        }
                    270: 
                    271: 
                    272: 
                    273: /* I dunno if this is right, but bash seems to expect it */
                    274: 
                    275:        curproc->sigmask &= ~(1L<<sig);
                    276: 
                    277: 
                    278: 
                    279:        return oldhandle;
                    280: 
                    281: }
                    282: 
                    283: 
                    284: 
                    285: /*
                    286: 
                    287:  * block some signals. Returns the old signal mask.
                    288: 
                    289:  */
                    290: 
                    291: 
                    292: 
1.1.1.2   root      293: long ARGS_ON_STACK
1.1       root      294: 
                    295: p_sigblock(mask)
                    296: 
                    297:        ulong mask;
                    298: 
                    299: {
                    300: 
                    301:        ulong oldmask;
                    302: 
                    303: 
                    304: 
1.1.1.2   root      305:        TRACE(("Psigblock(%lx)",mask));
1.1       root      306: 
                    307: /* some signals (e.g. SIGKILL) can't be masked */
                    308: 
                    309:        mask &= ~(UNMASKABLE);
                    310: 
                    311:        oldmask = curproc->sigmask;
                    312: 
                    313:        curproc->sigmask |= mask;
                    314: 
                    315:        return oldmask;
                    316: 
                    317: }
                    318: 
                    319: 
                    320: 
                    321: /*
                    322: 
                    323:  * set the signals that we're blocking. Some signals (e.g. SIGKILL)
                    324: 
                    325:  * can't be masked.
                    326: 
                    327:  * Returns the old mask.
                    328: 
                    329:  */
                    330: 
                    331: 
                    332: 
1.1.1.2   root      333: long ARGS_ON_STACK
1.1       root      334: 
                    335: p_sigsetmask(mask)
                    336: 
                    337:        ulong mask;
                    338: 
                    339: {
                    340: 
                    341:        ulong oldmask;
                    342: 
                    343: 
                    344: 
1.1.1.2   root      345:        TRACE(("Psigsetmask(%lx)",mask));
1.1       root      346: 
                    347:        oldmask = curproc->sigmask;
                    348: 
                    349:        curproc->sigmask = mask & ~(UNMASKABLE);
                    350: 
                    351:        check_sigs();   /* maybe we unmasked something */
                    352: 
                    353:        return oldmask;
                    354: 
                    355: }
                    356: 
                    357: 
                    358: 
                    359: /*
                    360: 
                    361:  * p_sigpending: return which signals are pending delivery
                    362: 
                    363:  */
                    364: 
                    365: 
                    366: 
1.1.1.2   root      367: long ARGS_ON_STACK
1.1       root      368: 
                    369: p_sigpending()
                    370: 
                    371: {
                    372: 
1.1.1.2   root      373:        TRACE(("Psigpending()"));
1.1       root      374: 
                    375:        check_sigs();   /* clear out any that are going to be delivered soon */
                    376: 
1.1.1.2   root      377: 
                    378: 
                    379: /* note that signal #0 is used internally, so we don't tell the process
                    380: 
                    381:  * about it
                    382: 
                    383:  */
                    384: 
                    385:        return curproc->sigpending & ~1L;
1.1       root      386: 
                    387: }
                    388: 
                    389: 
                    390: 
                    391: /*
                    392: 
                    393:  * p_sigpause: atomically set the signals that we're blocking, then pause.
                    394: 
                    395:  * Some signals (e.g. SIGKILL) can't be masked.
                    396: 
                    397:  */
                    398: 
                    399: 
                    400: 
1.1.1.2   root      401: long ARGS_ON_STACK
1.1       root      402: 
                    403: p_sigpause(mask)
                    404: 
                    405:        ulong mask;
                    406: 
                    407: {
                    408: 
                    409:        ulong oldmask;
                    410: 
                    411: 
                    412: 
1.1.1.2   root      413:        TRACE(("Psigpause(%lx)", mask));
1.1       root      414: 
                    415:        oldmask = curproc->sigmask;
                    416: 
                    417:        curproc->sigmask = mask & ~(UNMASKABLE);
                    418: 
                    419:        if (curproc->sigpending & ~(curproc->sigmask))
                    420: 
                    421:                check_sigs();   /* a signal is immediately pending */
                    422: 
                    423:        else
                    424: 
                    425:                sleep(IO_Q, -1L);
                    426: 
                    427:        curproc->sigmask = oldmask;
                    428: 
                    429:        check_sigs();   /* maybe we unmasked something */
                    430: 
1.1.1.2   root      431:        TRACE(("Psigpause: returning OK"));
1.1       root      432: 
                    433:        return 0;
                    434: 
                    435: }
                    436: 
1.1.1.4 ! root      437: 
        !           438: 
        !           439: /*
        !           440: 
        !           441:  * p_sigintr: Set an exception vector to send us the specified signal.
        !           442: 
        !           443:  */
        !           444: 
        !           445: 
        !           446: 
        !           447: typedef struct usig {
        !           448: 
        !           449:        int vec;                /* exception vector number */
        !           450: 
        !           451:        int sig;                /* signal to send */
        !           452: 
        !           453:        PROC *proc;             /* process to get signal */
        !           454: 
        !           455:        long oldv;              /* old exception vector value */
        !           456: 
        !           457:        struct usig *next;      /* next entry ... */
        !           458: 
        !           459: } usig;
        !           460: 
        !           461: 
        !           462: 
        !           463: static usig *usiglst;
        !           464: 
        !           465: extern long mcpu;
        !           466: 
        !           467: 
        !           468: 
        !           469: long ARGS_ON_STACK
        !           470: 
        !           471: p_sigintr(vec, sig)
        !           472: 
        !           473:        int vec;
        !           474: 
        !           475:        int sig;
        !           476: 
        !           477: {
        !           478: 
        !           479:        extern void new_intr(); /* in intr.spp */
        !           480: 
        !           481:        long vec2;
        !           482: 
        !           483:        usig *new;
        !           484: 
        !           485: 
        !           486: 
        !           487:        if (!sig)               /* ignore signal 0 */
        !           488: 
        !           489:                return 0;
        !           490: 
        !           491: 
        !           492: 
        !           493:        vec2 = (long) new_intr;
        !           494: 
        !           495: 
        !           496: 
        !           497: #ifndef ONLY030
        !           498: 
        !           499:        if (mcpu == 0)                  
        !           500: 
        !           501:                /* put vector number in high byte of vector address */
        !           502: 
        !           503:                vec2 |= ((long) vec) << 24;
        !           504: 
        !           505: #endif
        !           506: 
        !           507:        new = kmalloc(sizeof(usig));
        !           508: 
        !           509:        if (!new)                       /* hope this never happens...! */
        !           510: 
        !           511:                return ENSMEM;
        !           512: 
        !           513:        new->vec = vec;
        !           514: 
        !           515:        new->sig = sig;
        !           516: 
        !           517:        new->proc = curproc;
        !           518: 
        !           519:        new->next = usiglst;            /* simple unsorted list... */
        !           520: 
        !           521:        usiglst = new;
        !           522: 
        !           523: 
        !           524: 
        !           525:        new->oldv = setexc(vec, vec2);
        !           526: 
        !           527:        return new->oldv;
        !           528: 
        !           529: }
        !           530: 
        !           531: 
        !           532: 
        !           533: /*
        !           534: 
        !           535:  * Find the process that requested this interrupt, and send it a signal.
        !           536: 
        !           537:  * Called at interrupt time by new_intr() from intr.spp, with interrupt
        !           538: 
        !           539:  * vector number on the stack.
        !           540: 
        !           541:  */
        !           542: 
        !           543: 
        !           544: 
        !           545: void ARGS_ON_STACK
        !           546: 
        !           547: sig_user(vec)
        !           548: 
        !           549:        int vec;
        !           550: 
        !           551: {
        !           552: 
        !           553:        usig *ptr;
        !           554: 
        !           555: 
        !           556: 
        !           557:        for (ptr = usiglst; ptr; ptr=ptr->next)
        !           558: 
        !           559:                if (vec == ptr->vec) {
        !           560: 
        !           561:                        if (ptr->proc->wait_q != ZOMBIE_Q &&
        !           562: 
        !           563:                            ptr->proc->wait_q != TSR_Q) {
        !           564: 
        !           565:                                post_sig(ptr->proc, ptr->sig);
        !           566: 
        !           567:                        }
        !           568: 
        !           569: #if 0  /* Search entire list, to allow multiple processes to respond to
        !           570: 
        !           571:           the same interrupt. (Why/when would you want that?) */
        !           572: 
        !           573:                        break;
        !           574: 
        !           575: #endif
        !           576: 
        !           577:                }
        !           578: 
        !           579:        /*
        !           580: 
        !           581:         * Clear in-service bit for ST MFP interrupts
        !           582: 
        !           583:         */
        !           584: 
        !           585:        if (vec >= 64 && vec < 80) {
        !           586: 
        !           587:                char *mfp, c;
        !           588: 
        !           589: 
        !           590: 
        !           591:                if (vec < 72)           /* Register B */
        !           592: 
        !           593:                        mfp = (char *)0xfffffa11L;
        !           594: 
        !           595:                else                    /* Register A */
        !           596: 
        !           597:                        mfp = (char *)0xfffffa0fL;
        !           598: 
        !           599:                c = 1 << (vec & 7);
        !           600: 
        !           601: 
        !           602: 
        !           603:                *mfp = ~c;
        !           604: 
        !           605:        }
        !           606: 
        !           607: }
        !           608: 
        !           609: 
        !           610: 
        !           611: /*
        !           612: 
        !           613:  * cancelsigintrs: remove any interrupts requested by this process, called
        !           614: 
        !           615:  * at process termination.
        !           616: 
        !           617:  */
        !           618: 
        !           619: void
        !           620: 
        !           621: cancelsigintrs()
        !           622: 
        !           623: {
        !           624: 
        !           625:        usig *ptr, **old, *nxt;
        !           626: 
        !           627:        short s = spl7();
        !           628: 
        !           629: 
        !           630: 
        !           631:        for (old=&usiglst, ptr=usiglst; ptr; ) {
        !           632: 
        !           633:                nxt = ptr->next;
        !           634: 
        !           635:                if (ptr->proc == curproc) {
        !           636: 
        !           637:                        setexc(ptr->vec, ptr->oldv);
        !           638: 
        !           639:                        *old = nxt;
        !           640: 
        !           641:                        kfree(ptr);
        !           642: 
        !           643:                } else {
        !           644: 
        !           645:                        old = &(ptr->next);
        !           646: 
        !           647:                }
        !           648: 
        !           649:                ptr = nxt;
        !           650: 
        !           651:        }
        !           652: 
        !           653:        spl(s);
        !           654: 
        !           655: }
        !           656: 

unix.superglobalmegacorp.com

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