Annotation of 43BSD/contrib/mh/miscellany/less/:signal.c, revision 1.1.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.