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: #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.