[BACK]Return to signal.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / less

Annotation of src/usr.bin/less/signal.c, Revision 1.1.1.2

1.1       etheisen    1: /*
1.1.1.2 ! millert     2:  * Copyright (C) 1984-2002  Mark Nudelman
1.1       etheisen    3:  *
1.1.1.2 ! millert     4:  * You may distribute under the terms of either the GNU General Public
        !             5:  * License or the Less License, as specified in the README file.
1.1       etheisen    6:  *
1.1.1.2 ! millert     7:  * For more information about less, or for information on how to
        !             8:  * contact the author, see the README file.
1.1       etheisen    9:  */
                     10:
                     11:
                     12: /*
                     13:  * Routines dealing with signals.
                     14:  *
                     15:  * A signal usually merely causes a bit to be set in the "signals" word.
                     16:  * At some convenient time, the mainline code checks to see if any
                     17:  * signals need processing by calling psignal().
                     18:  * If we happen to be reading from a file [in iread()] at the time
                     19:  * the signal is received, we call intread to interrupt the iread.
                     20:  */
                     21:
                     22: #include "less.h"
                     23: #include <signal.h>
                     24:
                     25: /*
                     26:  * "sigs" contains bits indicating signals which need to be processed.
                     27:  */
                     28: public int sigs;
                     29:
                     30: extern int sc_width, sc_height;
                     31: extern int screen_trashed;
                     32: extern int lnloop;
                     33: extern int linenums;
                     34: extern int wscroll;
                     35: extern int reading;
                     36:
                     37: /*
                     38:  * Interrupt signal handler.
                     39:  */
                     40:        /* ARGSUSED*/
                     41:        static RETSIGTYPE
                     42: u_interrupt(type)
                     43:        int type;
                     44: {
                     45: #if OS2
1.1.1.2 ! millert    46:        LSIGNAL(SIGINT, SIG_ACK);
1.1       etheisen   47: #endif
1.1.1.2 ! millert    48:        LSIGNAL(SIGINT, u_interrupt);
1.1       etheisen   49:        sigs |= S_INTERRUPT;
1.1.1.2 ! millert    50: #if MSDOS_COMPILER==DJGPPC
        !            51:        /*
        !            52:         * If a keyboard has been hit, it must be Ctrl-C
        !            53:         * (as opposed to Ctrl-Break), so consume it.
        !            54:         * (Otherwise, Less will beep when it sees Ctrl-C from keyboard.)
        !            55:         */
        !            56:        if (kbhit())
        !            57:                getkey();
        !            58: #endif
1.1       etheisen   59:        if (reading)
                     60:                intread();
                     61: }
                     62:
                     63: #ifdef SIGTSTP
                     64: /*
                     65:  * "Stop" (^Z) signal handler.
                     66:  */
                     67:        /* ARGSUSED*/
                     68:        static RETSIGTYPE
                     69: stop(type)
                     70:        int type;
                     71: {
1.1.1.2 ! millert    72:        LSIGNAL(SIGTSTP, stop);
1.1       etheisen   73:        sigs |= S_STOP;
                     74:        if (reading)
                     75:                intread();
                     76: }
                     77: #endif
                     78:
                     79: #ifdef SIGWINCH
                     80: /*
                     81:  * "Window" change handler
                     82:  */
                     83:        /* ARGSUSED*/
                     84:        public RETSIGTYPE
                     85: winch(type)
                     86:        int type;
                     87: {
1.1.1.2 ! millert    88:        LSIGNAL(SIGWINCH, winch);
1.1       etheisen   89:        sigs |= S_WINCH;
                     90:        if (reading)
                     91:                intread();
                     92: }
                     93: #else
                     94: #ifdef SIGWIND
                     95: /*
                     96:  * "Window" change handler
                     97:  */
                     98:        /* ARGSUSED*/
                     99:        public RETSIGTYPE
                    100: winch(type)
                    101:        int type;
                    102: {
1.1.1.2 ! millert   103:        LSIGNAL(SIGWIND, winch);
1.1       etheisen  104:        sigs |= S_WINCH;
                    105:        if (reading)
                    106:                intread();
                    107: }
                    108: #endif
                    109: #endif
                    110:
1.1.1.2 ! millert   111: #if MSDOS_COMPILER==WIN32C
        !           112: /*
        !           113:  * Handle CTRL-C and CTRL-BREAK keys.
        !           114:  */
        !           115: #include "windows.h"
        !           116:
        !           117:        static BOOL WINAPI
        !           118: wbreak_handler(dwCtrlType)
        !           119:        DWORD dwCtrlType;
        !           120: {
        !           121:        switch (dwCtrlType)
        !           122:        {
        !           123:        case CTRL_C_EVENT:
        !           124:        case CTRL_BREAK_EVENT:
        !           125:                sigs |= S_INTERRUPT;
        !           126:                return (TRUE);
        !           127:        default:
        !           128:                break;
        !           129:        }
        !           130:        return (FALSE);
        !           131: }
        !           132: #endif
        !           133:
1.1       etheisen  134: /*
                    135:  * Set up the signal handlers.
                    136:  */
                    137:        public void
                    138: init_signals(on)
                    139:        int on;
                    140: {
                    141:        if (on)
                    142:        {
                    143:                /*
                    144:                 * Set signal handlers.
                    145:                 */
1.1.1.2 ! millert   146:                (void) LSIGNAL(SIGINT, u_interrupt);
        !           147: #if MSDOS_COMPILER==WIN32C
        !           148:                SetConsoleCtrlHandler(wbreak_handler, TRUE);
        !           149: #endif
1.1       etheisen  150: #ifdef SIGTSTP
1.1.1.2 ! millert   151:                (void) LSIGNAL(SIGTSTP, stop);
1.1       etheisen  152: #endif
                    153: #ifdef SIGWINCH
1.1.1.2 ! millert   154:                (void) LSIGNAL(SIGWINCH, winch);
1.1       etheisen  155: #else
                    156: #ifdef SIGWIND
1.1.1.2 ! millert   157:                (void) LSIGNAL(SIGWIND, winch);
        !           158: #endif
        !           159: #ifdef SIGQUIT
        !           160:                (void) LSIGNAL(SIGQUIT, SIG_IGN);
1.1       etheisen  161: #endif
                    162: #endif
                    163:        } else
                    164:        {
                    165:                /*
                    166:                 * Restore signals to defaults.
                    167:                 */
1.1.1.2 ! millert   168:                (void) LSIGNAL(SIGINT, SIG_DFL);
        !           169: #if MSDOS_COMPILER==WIN32C
        !           170:                SetConsoleCtrlHandler(wbreak_handler, FALSE);
        !           171: #endif
1.1       etheisen  172: #ifdef SIGTSTP
1.1.1.2 ! millert   173:                (void) LSIGNAL(SIGTSTP, SIG_DFL);
1.1       etheisen  174: #endif
                    175: #ifdef SIGWINCH
1.1.1.2 ! millert   176:                (void) LSIGNAL(SIGWINCH, SIG_IGN);
1.1       etheisen  177: #endif
                    178: #ifdef SIGWIND
1.1.1.2 ! millert   179:                (void) LSIGNAL(SIGWIND, SIG_IGN);
        !           180: #endif
        !           181: #ifdef SIGQUIT
        !           182:                (void) LSIGNAL(SIGQUIT, SIG_DFL);
1.1       etheisen  183: #endif
                    184:        }
                    185: }
                    186:
                    187: /*
                    188:  * Process any signals we have received.
                    189:  * A received signal cause a bit to be set in "sigs".
                    190:  */
                    191:        public void
                    192: psignals()
                    193: {
                    194:        register int tsignals;
                    195:
                    196:        if ((tsignals = sigs) == 0)
                    197:                return;
                    198:        sigs = 0;
                    199:
                    200: #ifdef SIGTSTP
                    201:        if (tsignals & S_STOP)
                    202:        {
                    203:                /*
                    204:                 * Clean up the terminal.
                    205:                 */
                    206: #ifdef SIGTTOU
1.1.1.2 ! millert   207:                LSIGNAL(SIGTTOU, SIG_IGN);
1.1       etheisen  208: #endif
                    209:                clear_bot();
                    210:                deinit();
                    211:                flush();
                    212:                raw_mode(0);
                    213: #ifdef SIGTTOU
1.1.1.2 ! millert   214:                LSIGNAL(SIGTTOU, SIG_DFL);
1.1       etheisen  215: #endif
1.1.1.2 ! millert   216:                LSIGNAL(SIGTSTP, SIG_DFL);
1.1       etheisen  217:                kill(getpid(), SIGTSTP);
                    218:                /*
                    219:                 * ... Bye bye. ...
                    220:                 * Hopefully we'll be back later and resume here...
                    221:                 * Reset the terminal and arrange to repaint the
                    222:                 * screen when we get back to the main command loop.
                    223:                 */
1.1.1.2 ! millert   224:                LSIGNAL(SIGTSTP, stop);
1.1       etheisen  225:                raw_mode(1);
                    226:                init();
                    227:                screen_trashed = 1;
                    228:                tsignals |= S_WINCH;
                    229:        }
                    230: #endif
                    231: #ifdef S_WINCH
                    232:        if (tsignals & S_WINCH)
                    233:        {
                    234:                int old_width, old_height;
                    235:                /*
                    236:                 * Re-execute scrsize() to read the new window size.
                    237:                 */
                    238:                old_width = sc_width;
                    239:                old_height = sc_height;
                    240:                get_term();
                    241:                if (sc_width != old_width || sc_height != old_height)
                    242:                {
                    243:                        wscroll = (sc_height + 1) / 2;
                    244:                        screen_trashed = 1;
                    245:                }
                    246:        }
                    247: #endif
                    248:        if (tsignals & S_INTERRUPT)
                    249:        {
                    250:                bell();
                    251:                /*
                    252:                 * {{ You may wish to replace the bell() with
                    253:                 *    error("Interrupt", NULL_PARG); }}
                    254:                 */
                    255:
                    256:                /*
                    257:                 * If we were interrupted while in the "calculating
                    258:                 * line numbers" loop, turn off line numbers.
                    259:                 */
                    260:                if (lnloop)
                    261:                {
                    262:                        lnloop = 0;
                    263:                        if (linenums == 2)
                    264:                                screen_trashed = 1;
                    265:                        linenums = 0;
                    266:                        error("Line numbers turned off", NULL_PARG);
                    267:                }
                    268:
                    269:        }
                    270: }