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: 
        !            33: extern int reading;
        !            34: extern char *first_cmd;
        !            35: extern jmp_buf main_loop;
        !            36: 
        !            37: /*
        !            38:  * Interrupt signal handler.
        !            39:  */
        !            40:        static HANDLER
        !            41: interrupt()
        !            42: {
        !            43:        SIGNAL(SIGINT, interrupt);
        !            44:        sigs |= S_INTERRUPT;
        !            45:        if (reading)
        !            46:                psignals();
        !            47: }
        !            48: 
        !            49: #ifdef SIGTSTP
        !            50: /*
        !            51:  * "Stop" (^Z) signal handler.
        !            52:  */
        !            53:        static HANDLER
        !            54: stop()
        !            55: {
        !            56:        SIGNAL(SIGTSTP, stop);
        !            57:        sigs |= S_STOP;
        !            58:        if (reading)
        !            59:                psignals();
        !            60: }
        !            61: #endif
        !            62: 
        !            63: /*
        !            64:  * Set up the signal handlers.
        !            65:  */
        !            66:        public void
        !            67: init_signals()
        !            68: {
        !            69:        (void) SIGNAL(SIGINT, interrupt);
        !            70: #ifdef SIGTSTP
        !            71:        (void) SIGNAL(SIGTSTP, stop);
        !            72: #endif
        !            73: }
        !            74: 
        !            75: /*
        !            76:  * Process any signals we have recieved.
        !            77:  * A received signal cause a bit to be set in "sigs".
        !            78:  */
        !            79:        public void 
        !            80: psignals()
        !            81: {
        !            82:        register int tsignals;
        !            83: 
        !            84:        tsignals = sigs;
        !            85:        sigs = 0;
        !            86:        if (tsignals == 0)
        !            87:                return;
        !            88: 
        !            89:        dropout();              /* Discard any buffered output */
        !            90: 
        !            91: #ifdef SIGTSTP
        !            92:        if (tsignals & S_STOP)
        !            93:        {
        !            94:                /*
        !            95:                 * Clean up the terminal.
        !            96:                 */
        !            97: #ifdef SIGTTOU
        !            98:                SIGNAL(SIGTTOU, SIG_IGN);
        !            99: #endif
        !           100:                lower_left();
        !           101:                clear_eol();
        !           102:                flush();
        !           103:                raw_mode(0);
        !           104: #ifdef SIGTTOU
        !           105:                SIGNAL(SIGTTOU, SIG_DFL);
        !           106: #endif
        !           107:                SIGNAL(SIGTSTP, SIG_DFL);
        !           108: #if SIGSETMASK
        !           109:                /*
        !           110:                 * This system will not allow us to send a 
        !           111:                 * stop signal (SIGTSTP) to ourself
        !           112:                 * while we are in the signal handler, like maybe now.
        !           113:                 * (This can be the case if we are reading; see comment above.)
        !           114:                 * So we ask the silly system for permission to do so.
        !           115:                 */
        !           116:                sigsetmask(0);
        !           117: #endif
        !           118:                kill(getpid(), SIGTSTP);
        !           119:                /*
        !           120:                 * ... Bye bye. ...
        !           121:                 * Hopefully we'll be back later and resume here...
        !           122:                 * Reset the terminal and arrange to repaint the
        !           123:                 * screen when we get back to the main command loop.
        !           124:                 */
        !           125:                SIGNAL(SIGTSTP, stop);
        !           126:                raw_mode(1);
        !           127:                first_cmd = "r";
        !           128:                longjmp(main_loop, 1);
        !           129:        }
        !           130: #endif
        !           131:        if (tsignals & S_INTERRUPT)
        !           132:        {
        !           133:                bell();
        !           134:                /*
        !           135:                 * {{ You may wish to replace the bell() with 
        !           136:                 *    error("Interrupt"); }}
        !           137:                 */
        !           138:        }
        !           139: 
        !           140:        longjmp(main_loop, 1);
        !           141: }
        !           142: 
        !           143: /*
        !           144:  * Pass the specified command to a shell to be executed.
        !           145:  * Like plain "system()", but handles resetting terminal modes, etc.
        !           146:  */
        !           147:        public void
        !           148: lsystem(cmd)
        !           149:        char *cmd;
        !           150: {
        !           151:        int inp;
        !           152: 
        !           153:        /*
        !           154:         * Print the command which is to be executed.
        !           155:         */
        !           156:        lower_left();
        !           157:        clear_eol();
        !           158:        puts("!");
        !           159:        puts(cmd);
        !           160:        puts("\n");
        !           161: 
        !           162:        /*
        !           163:         * De-initialize the terminal and take out of raw mode.
        !           164:         */
        !           165:        deinit();
        !           166:        flush();
        !           167:        raw_mode(0);
        !           168: 
        !           169:        /*
        !           170:         * Restore signals to their defaults.
        !           171:         */
        !           172:        SIGNAL(SIGINT, SIG_DFL);
        !           173: #ifdef SIGTSTP
        !           174:        SIGNAL(SIGTSTP, SIG_DFL);
        !           175: #endif
        !           176:        /*
        !           177:         * Pass the command to the system to be executed.
        !           178:         */
        !           179:        inp = dup(0);
        !           180:        close(0);
        !           181:        open("/dev/tty", 0);
        !           182: 
        !           183:        system(cmd);
        !           184: 
        !           185:        close(0);
        !           186:        dup(inp);
        !           187:        close(inp);
        !           188: 
        !           189:        /*
        !           190:         * Reset signals, raw mode, etc.
        !           191:         */
        !           192:        init_signals();
        !           193:        raw_mode(1);
        !           194:        init();
        !           195: }

unix.superglobalmegacorp.com

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