Annotation of researchv10no/lbin/mailx/sigretro.c, revision 1.1

1.1     ! root        1: #ident "@(#)sigretro.c 1.3 'attmail mail(1) command'"
        !             2: #ident "@(#)mailx:sigretro.c   1.6.1.1"
        !             3: /*     Copyright (c) 1984 AT&T */
        !             4: /*       All Rights Reserved   */
        !             5: 
        !             6: /*     THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T     */
        !             7: /*     The copyright notice above does not evidence any        */
        !             8: /*     actual or intended publication of such source code.     */
        !             9: 
        !            10: #ident "@(#)mailx:sigretro.c   1.6"
        !            11: 
        !            12: /*
        !            13:  * mailx -- a modified version of a University of California at Berkeley
        !            14:  *     mail program
        !            15:  */
        !            16: 
        !            17: /*
        !            18:  * This code is only compiled in if SIG_HOLD is not defined!
        !            19:  *
        !            20:  * Retrofit new signal interface to old signal primitives.
        !            21:  * Supported routines:
        !            22:  *     sigsys(sig, func)
        !            23:  *     sigset(sig, func)
        !            24:  *     sighold(sig)
        !            25:  *     sigrelse(sig)
        !            26:  *     sigignore(sig)
        !            27:  *     sigpause(sig)
        !            28:  * Also,
        !            29:  *     sigchild()
        !            30:  *             to set all held signals to ignored signals in the
        !            31:  *             child process after fork(2)
        !            32:  */
        !            33: #include <rcv.h>                               /* find out if we're in USG -- adb */
        !            34: #include <signal.h>
        !            35: 
        !            36: #ifndef USG
        !            37: # include <errno.h>
        !            38: extern int errno;
        !            39: 
        !            40: typedef void   (*sigtype)();
        !            41: 
        !            42: #ifndef SIG_HOLD                                                       /* adb */
        !            43: #define SIG_HOLD       ((sigtype) 2)
        !            44: #endif
        !            45: #ifndef SIG_ERR
        !            46: # define SIG_ERR       ((sigtype) -1)
        !            47: #endif
        !            48: 
        !            49: sigtype        sigdisp(), sighold(), sigignore();
        !            50: void   _Sigtramp();
        !            51: 
        !            52: /*
        !            53:  * The following helps us keep the extended signal semantics together.
        !            54:  * We remember for each signal the address of the function we're
        !            55:  * supposed to call.  s_func is SIG_DFL / SIG_IGN if appropriate.
        !            56:  */
        !            57: static struct sigtable {
        !            58:        sigtype s_func;                 /* What to call */
        !            59:        int     s_flag;                 /* Signal flags; see below */
        !            60: } sigtable[NSIG + 1];
        !            61: 
        !            62: /*
        !            63:  * Signal flag values.
        !            64:  */
        !            65: #define        SHELD           1               /* Signal is being held */
        !            66: #define        SDEFER          2               /* Signal occured while held */
        !            67: #define        SSET            4               /* s_func is believable */
        !            68: #define        SPAUSE          8               /* are pausing, waiting for sig */
        !            69: 
        !            70: jmp_buf        _pause;                         /* For doing sigpause() */
        !            71: 
        !            72: /*
        !            73:  * Approximate sigsys() system call
        !            74:  * This is almost useless since one only calls sigsys()
        !            75:  * in the child of a fork().  If you have vfork(), you have new signals
        !            76:  * anyway.  The real sigsys() does all the stuff needed to support
        !            77:  * the real sigset() library.  We don't bother here, assuming that
        !            78:  * you are either ignoring or defaulting a signal in the child.
        !            79:  */
        !            80: sigtype
        !            81: sigsys(sig, func)
        !            82:        sigtype func;
        !            83: {
        !            84:        sigtype old;
        !            85: 
        !            86:        old = sigdisp(sig);
        !            87:        signal(sig, func);
        !            88:        return(old);
        !            89: }
        !            90: 
        !            91: 
        !            92: /*
        !            93:  * Set the (permanent) disposition of a signal.
        !            94:  * If the signal is subsequently (or even now) held,
        !            95:  * the action you set here can be enabled using sigrelse().
        !            96:  */
        !            97: sigtype
        !            98: sigset(sig, func)
        !            99:        sigtype func;
        !           100: {
        !           101:        sigtype old;
        !           102: 
        !           103:        if (sig < 1 || sig > NSIG) {
        !           104:                errno = EINVAL;
        !           105:                return(SIG_ERR);
        !           106:        }
        !           107:        old = sigdisp(sig);
        !           108:        /*
        !           109:         * Does anyone actually call sigset with SIG_HOLD!?
        !           110:         */
        !           111:        if (func == (void (*)())SIG_HOLD) {                             /* adb */
        !           112:                sighold(sig);
        !           113:                return(old);
        !           114:        }
        !           115:        sigtable[sig].s_flag |= SSET;
        !           116:        sigtable[sig].s_func = func;
        !           117:        if (func == (void (*)())SIG_DFL) {                              /* adb */
        !           118:                /*
        !           119:                 * If signal has been held, must retain
        !           120:                 * the catch so that we can note occurrance
        !           121:                 * of signal.
        !           122:                 */
        !           123:                if ((sigtable[sig].s_flag & SHELD) == 0)
        !           124:                        signal(sig, SIG_DFL);
        !           125:                else
        !           126:                        signal(sig, _Sigtramp);
        !           127:                return(old);
        !           128:        }
        !           129:        if (func == (void (*)())SIG_IGN) {                              /* adb */
        !           130:                /*
        !           131:                 * Clear pending signal
        !           132:                 */
        !           133:                signal(sig, SIG_IGN);
        !           134:                sigtable[sig].s_flag &= ~SDEFER;
        !           135:                return(old);
        !           136:        }
        !           137:        signal(sig, _Sigtramp);
        !           138:        return(old);
        !           139: }
        !           140: 
        !           141: /*
        !           142:  * Hold a signal.
        !           143:  * This CAN be tricky if the signal's disposition is SIG_DFL.
        !           144:  * In that case, we still catch the signal so we can note it
        !           145:  */
        !           146: sigtype
        !           147: sighold(sig)
        !           148: {
        !           149:        sigtype old;
        !           150: 
        !           151:        if (sig < 1 || sig > NSIG) {
        !           152:                errno = EINVAL;
        !           153:                return(SIG_ERR);
        !           154:        }
        !           155:        old = sigdisp(sig);
        !           156:        if (sigtable[sig].s_flag & SHELD)
        !           157:                return(old);
        !           158:        /*
        !           159:         * When the default action is required, we have to
        !           160:         * set up to catch the signal to note signal's occurrance.
        !           161:         */
        !           162:        if (old == (void (*)())SIG_DFL) {                               /* adb */
        !           163:                sigtable[sig].s_flag |= SSET;
        !           164:                signal(sig, _Sigtramp);
        !           165:        }
        !           166:        sigtable[sig].s_flag |= SHELD;
        !           167:        return(old);
        !           168: }
        !           169: 
        !           170: /*
        !           171:  * Release a signal
        !           172:  * If the signal occurred while we had it held, cause the signal.
        !           173:  */
        !           174: sigtype
        !           175: sigrelse(sig)
        !           176: {
        !           177:        sigtype old;
        !           178: 
        !           179:        if (sig < 1 || sig > NSIG) {
        !           180:                errno = EINVAL;
        !           181:                return(SIG_ERR);
        !           182:        }
        !           183:        old = sigdisp(sig);
        !           184:        if ((sigtable[sig].s_flag & SHELD) == 0)
        !           185:                return(old);
        !           186:        sigtable[sig].s_flag &= ~SHELD;
        !           187:        if (sigtable[sig].s_flag & SDEFER)
        !           188:                _Sigtramp(sig);
        !           189:        /*
        !           190:         * If disposition was the default, then we can unset the
        !           191:         * catch to _Sigtramp() and let the system do the work.
        !           192:         */
        !           193:        if (sigtable[sig].s_func == (void (*)())SIG_DFL)                /* adb */
        !           194:                signal(sig, SIG_DFL);
        !           195:        return(old);
        !           196: }
        !           197: 
        !           198: /*
        !           199:  * Ignore a signal.
        !           200:  */
        !           201: sigtype
        !           202: sigignore(sig)
        !           203: {
        !           204:        return(sigset(sig, SIG_IGN));
        !           205: }
        !           206: 
        !           207: /*
        !           208:  * Pause, waiting for sig to occur.
        !           209:  * We assume LUSER called us with the signal held.
        !           210:  * When we got the signal, mark the signal as having
        !           211:  * occurred.  It will actually cause something when
        !           212:  * the signal is released.
        !           213:  */
        !           214: sigpause(sig)
        !           215: {
        !           216:        if (sig < 1 || sig > NSIG) {
        !           217:                errno = EINVAL;
        !           218:                return;
        !           219:        }
        !           220:        sigtable[sig].s_flag |= SHELD|SPAUSE;
        !           221:        if (setjmp(_pause) == 0)
        !           222:                pause();
        !           223:        sigtable[sig].s_flag &= ~SPAUSE;
        !           224:        sigtable[sig].s_flag |= SDEFER;
        !           225: }
        !           226: 
        !           227: /*
        !           228:  * In the child process after fork(2), set the disposition of all held
        !           229:  * signals to SIG_IGN.  This is a new procedure not in the real sigset()
        !           230:  * package, provided for retrofitting purposes.
        !           231:  */
        !           232: void
        !           233: sigchild()
        !           234: {
        !           235:        register int i;
        !           236: 
        !           237:        for (i = 1; i <= NSIG; i++)
        !           238:                if (sigtable[i].s_flag & SHELD)
        !           239:                        signal(i, SIG_IGN);
        !           240: }
        !           241: 
        !           242: 
        !           243: /*
        !           244:  * Return the current disposition of a signal
        !           245:  * If we have not set this signal before, we have to
        !           246:  * ask the system
        !           247:  */
        !           248: sigtype
        !           249: sigdisp(sig)
        !           250: {
        !           251:        sigtype old;
        !           252: 
        !           253:        if (sig < 1 || sig > NSIG) {
        !           254:                errno = EINVAL;
        !           255:                return(SIG_ERR);
        !           256:        }
        !           257:        /*
        !           258:         * If we have no knowledge of this signal,
        !           259:         * ask the system, then save the result for later.
        !           260:         */
        !           261:        if ((sigtable[sig].s_flag & SSET) == 0) {
        !           262:                old = (void (*)())signal(sig, SIG_IGN);                 /* adb */
        !           263:                sigtable[sig].s_func = old;
        !           264:                sigtable[sig].s_flag |= SSET;
        !           265:                signal(sig, old);
        !           266:                return(old);
        !           267:        }
        !           268:        /*
        !           269:         * If we have set this signal before, then sigset()
        !           270:         * will have been careful to leave something meaningful
        !           271:         * in s_func.
        !           272:         */
        !           273:        return(sigtable[sig].s_func);
        !           274: }
        !           275: 
        !           276: /*
        !           277:  * The following routine gets called for any signal
        !           278:  * that is to be trapped to a user function.
        !           279:  */
        !           280: void
        !           281: _Sigtramp(sig)
        !           282: {
        !           283:        sigtype old;
        !           284: 
        !           285:        if (sig < 1 || sig > NSIG) {
        !           286:                errno = EINVAL;
        !           287:                return;
        !           288:        }
        !           289: 
        !           290: top:
        !           291:        old = (void (*)())signal(sig, SIG_IGN);                         /* adb */
        !           292:        /*
        !           293:         * If signal being paused on, wakeup sigpause()
        !           294:         */
        !           295:        if (sigtable[sig].s_flag & SPAUSE)
        !           296:                longjmp(_pause, 1);
        !           297:        /*
        !           298:         * If signal is being held, mark its table entry
        !           299:         * so we can trigger it when signal is released.
        !           300:         * Then just return.
        !           301:         */
        !           302:        if (sigtable[sig].s_flag & SHELD) {
        !           303:                sigtable[sig].s_flag |= SDEFER;
        !           304:                signal(sig, _Sigtramp);
        !           305:                return;
        !           306:        }
        !           307:        /*
        !           308:         * If the signal is being ignored, just return.
        !           309:         * This would make SIGCONT more normal, but of course
        !           310:         * any system with SIGCONT also has the new signal pkg, so...
        !           311:         */
        !           312:        if (sigtable[sig].s_func == (void (*)())SIG_IGN)                /* adb */
        !           313:                return;
        !           314:        /*
        !           315:         * If the signal is SIG_DFL, then we probably got here
        !           316:         * by holding the signal, having it happen, then releasing
        !           317:         * the signal. 
        !           318:         */
        !           319:        if (sigtable[sig].s_func == (void (*)())SIG_DFL) {              /* adb */
        !           320:                signal(sig, SIG_DFL);
        !           321:                kill(getpid(), sig);
        !           322:                /* Will we get back here? */
        !           323:                return;
        !           324:        }
        !           325:        /*
        !           326:         * Looks like we should just cause the signal...
        !           327:         * We hold the signal for the duration of the user's
        !           328:         * code with the signal re-enabled.  If the signal
        !           329:         * happens again while in user code, we will recursively
        !           330:         * trap here and mark that we had another occurance
        !           331:         * and return to the user's trap code.  When we return
        !           332:         * from there, we can cause the signal again.
        !           333:         */
        !           334:        sigtable[sig].s_flag &= ~SDEFER;
        !           335:        sigtable[sig].s_flag |= SHELD;
        !           336:        signal(sig, _Sigtramp);
        !           337:        (*sigtable[sig].s_func)(sig);
        !           338:        /*
        !           339:         * If the signal re-occurred while in the user's routine,
        !           340:         * just go try it again...
        !           341:         */
        !           342:        sigtable[sig].s_flag &= ~SHELD;
        !           343:        if (sigtable[sig].s_flag & SDEFER)
        !           344:                goto top;
        !           345: }
        !           346: 
        !           347: #else
        !           348: /*
        !           349:  * In the child process after fork(2), set the disposition of all held
        !           350:  * signals to SIG_IGN.  This is a new procedure not in the real sigset()
        !           351:  * package, provided for retrofitting purposes. With the real sigset()
        !           352:  * package, this function is unnecessary.
        !           353:  */
        !           354: void sigchild() {}
        !           355: #endif

unix.superglobalmegacorp.com

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