Annotation of 43BSD/contrib/mh/miscellany/less/signal.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Routines dealing with signals.
        !             3:  *
        !             4:  * A signal usually merely causes a bit to be set in the "signals" word.
        !             5:  * At some convenient time, the mainline code checks to see if any
        !             6:  * signals need processing by calling psignal().
        !             7:  * An exception is made if we are reading from the keyboard when the
        !             8:  * signal is received.  Some operating systems will simply call the
        !             9:  * signal handler and NOT return from the read (with EINTR).
        !            10:  * To handle this case, we service the interrupt directly from
        !            11:  * the handler if we are reading from the keyboard.
        !            12:  */
        !            13: 
        !            14: #include "less.h"
        !            15: #include <signal.h>
        !            16: #include <setjmp.h>
        !            17: 
        !            18: /*
        !            19:  * The type of signal handler functions.
        !            20:  * Usually int, although it should be void.
        !            21:  */
        !            22: typedef        int             HANDLER;
        !            23: 
        !            24: /*
        !            25:  * "sigs" contains bits indicating signals which need to be processed.
        !            26:  */
        !            27: public int sigs;
        !            28: #define        S_INTERRUPT     01
        !            29: #ifdef SIGTSTP
        !            30: #define        S_STOP          02
        !            31: #endif
        !            32: #ifdef NRTC
        !            33: #define        S_QUIT          04
        !            34: #endif NRTC
        !            35: 
        !            36: extern int reading;
        !            37: extern char *first_cmd;
        !            38: extern jmp_buf main_loop;
        !            39: 
        !            40: /*
        !            41:  * Interrupt signal handler.
        !            42:  */
        !            43:        static HANDLER
        !            44: interrupt()
        !            45: {
        !            46:        SIGNAL(SIGINT, interrupt);
        !            47:        sigs |= S_INTERRUPT;
        !            48:        if (reading)
        !            49:                psignals();
        !            50: }
        !            51: 
        !            52: #ifdef NRTC
        !            53: /*
        !            54:  * Interrupt signal handler.
        !            55:  */
        !            56:        static HANDLER
        !            57: quitnow ()
        !            58: {
        !            59:        SIGNAL(SIGQUIT, quitnow);
        !            60:        sigs |= S_QUIT;
        !            61:        if (reading)
        !            62:                psignals();
        !            63: }
        !            64: #endif NRTC
        !            65: 
        !            66: #ifdef SIGTSTP
        !            67: /*
        !            68:  * "Stop" (^Z) signal handler.
        !            69:  */
        !            70:        static HANDLER
        !            71: stop()
        !            72: {
        !            73:        SIGNAL(SIGTSTP, stop);
        !            74:        sigs |= S_STOP;
        !            75:        if (reading)
        !            76:                psignals();
        !            77: }
        !            78: #endif
        !            79: 
        !            80: /*
        !            81:  * Set up the signal handlers.
        !            82:  */
        !            83:        public void
        !            84: init_signals()
        !            85: {
        !            86:        (void) SIGNAL(SIGINT, interrupt);
        !            87: #ifdef NRTC
        !            88:        (void) SIGNAL (SIGQUIT, quitnow);
        !            89: #endif NRTC
        !            90: #ifdef SIGTSTP
        !            91:        (void) SIGNAL(SIGTSTP, stop);
        !            92: #endif
        !            93: }
        !            94: 
        !            95: /*
        !            96:  * Process any signals we have recieved.
        !            97:  * A received signal cause a bit to be set in "sigs".
        !            98:  */
        !            99:        public void 
        !           100: psignals()
        !           101: {
        !           102:        register int tsignals;
        !           103: 
        !           104:        tsignals = sigs;
        !           105:        sigs = 0;
        !           106:        if (tsignals == 0)
        !           107:                return;
        !           108: 
        !           109:        dropout();              /* Discard any buffered output */
        !           110: 
        !           111: #ifdef SIGTSTP
        !           112:        if (tsignals & S_STOP)
        !           113:        {
        !           114:                /*
        !           115:                 * Clean up the terminal.
        !           116:                 */
        !           117: #ifdef SIGTTOU
        !           118:                SIGNAL(SIGTTOU, SIG_IGN);
        !           119: #endif
        !           120:                lower_left();
        !           121:                clear_eol();
        !           122:                flush();
        !           123:                raw_mode(0);
        !           124: #ifdef SIGTTOU
        !           125:                SIGNAL(SIGTTOU, SIG_DFL);
        !           126: #endif
        !           127:                SIGNAL(SIGTSTP, SIG_DFL);
        !           128: #if SIGSETMASK
        !           129:                /*
        !           130:                 * This system will not allow us to send a 
        !           131:                 * stop signal (SIGTSTP) to ourself
        !           132:                 * while we are in the signal handler, like maybe now.
        !           133:                 * (This can be the case if we are reading; see comment above.)
        !           134:                 * So we ask the silly system for permission to do so.
        !           135:                 */
        !           136:                sigsetmask(0);
        !           137: #endif
        !           138:                kill(getpid(), SIGTSTP);
        !           139:                /*
        !           140:                 * ... Bye bye. ...
        !           141:                 * Hopefully we'll be back later and resume here...
        !           142:                 * Reset the terminal and arrange to repaint the
        !           143:                 * screen when we get back to the main command loop.
        !           144:                 */
        !           145:                SIGNAL(SIGTSTP, stop);
        !           146:                raw_mode(1);
        !           147:                first_cmd = "r";
        !           148:                longjmp(main_loop, 1);
        !           149:        }
        !           150: #endif
        !           151: #ifdef NRTC
        !           152:        if (tsignals & S_QUIT)
        !           153:                quit ();
        !           154: #endif NRTC
        !           155:        if (tsignals & S_INTERRUPT)
        !           156:        {
        !           157:                bell();
        !           158:                /*
        !           159:                 * {{ You may wish to replace the bell() with 
        !           160:                 *    error("Interrupt"); }}
        !           161:                 */
        !           162:        }
        !           163: 
        !           164:        longjmp(main_loop, 1);
        !           165: }
        !           166: 
        !           167: /*
        !           168:  * Pass the specified command to a shell to be executed.
        !           169:  * Like plain "system()", but handles resetting terminal modes, etc.
        !           170:  */
        !           171:        public void
        !           172: lsystem(cmd)
        !           173:        char *cmd;
        !           174: {
        !           175:        int inp;
        !           176: 
        !           177:        /*
        !           178:         * Print the command which is to be executed.
        !           179:         */
        !           180:        lower_left();
        !           181:        clear_eol();
        !           182:        puts("!");
        !           183:        puts(cmd);
        !           184:        puts("\n");
        !           185: 
        !           186:        /*
        !           187:         * De-initialize the terminal and take out of raw mode.
        !           188:         */
        !           189:        deinit();
        !           190:        flush();
        !           191:        raw_mode(0);
        !           192: 
        !           193:        /*
        !           194:         * Restore signals to their defaults.
        !           195:         */
        !           196:        SIGNAL(SIGINT, SIG_DFL);
        !           197: #ifdef SIGTSTP
        !           198:        SIGNAL(SIGTSTP, SIG_DFL);
        !           199: #endif
        !           200:        /*
        !           201:         * Pass the command to the system to be executed.
        !           202:         */
        !           203:        inp = dup(0);
        !           204:        close(0);
        !           205:        open("/dev/tty", 0);
        !           206: 
        !           207:        system(cmd);
        !           208: 
        !           209:        close(0);
        !           210:        dup(inp);
        !           211:        close(inp);
        !           212: 
        !           213:        /*
        !           214:         * Reset signals, raw mode, etc.
        !           215:         */
        !           216:        init_signals();
        !           217:        raw_mode(1);
        !           218:        init();
        !           219: }

unix.superglobalmegacorp.com

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