[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.8

1.1       etheisen    1: /*
1.7       shadchin    2:  * Copyright (C) 1984-2011  Mark Nudelman
1.1       etheisen    3:  *
1.4       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.4       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:  */
                     19:
                     20: #include "less.h"
                     21: #include <signal.h>
                     22:
                     23: /*
                     24:  * "sigs" contains bits indicating signals which need to be processed.
                     25:  */
1.8     ! millert    26: public volatile sig_atomic_t sigs;
1.1       etheisen   27:
                     28: extern int sc_width, sc_height;
                     29: extern int screen_trashed;
                     30: extern int lnloop;
                     31: extern int linenums;
                     32: extern int wscroll;
1.7       shadchin   33: extern int quit_on_intr;
                     34: extern long jump_sline_fraction;
1.1       etheisen   35:
                     36: /*
                     37:  * Interrupt signal handler.
                     38:  */
                     39:        /* ARGSUSED*/
                     40:        static RETSIGTYPE
                     41: u_interrupt(type)
                     42:        int type;
                     43: {
                     44: #if OS2
1.4       millert    45:        LSIGNAL(SIGINT, SIG_ACK);
1.1       etheisen   46: #endif
                     47:        sigs |= S_INTERRUPT;
1.4       millert    48: #if MSDOS_COMPILER==DJGPPC
                     49:        /*
                     50:         * If a keyboard has been hit, it must be Ctrl-C
                     51:         * (as opposed to Ctrl-Break), so consume it.
                     52:         * (Otherwise, Less will beep when it sees Ctrl-C from keyboard.)
                     53:         */
                     54:        if (kbhit())
                     55:                getkey();
                     56: #endif
1.1       etheisen   57: }
                     58:
                     59: #ifdef SIGTSTP
                     60: /*
                     61:  * "Stop" (^Z) signal handler.
                     62:  */
                     63:        /* ARGSUSED*/
                     64:        static RETSIGTYPE
                     65: stop(type)
                     66:        int type;
                     67: {
                     68:        sigs |= S_STOP;
                     69: }
                     70: #endif
                     71:
                     72: #ifdef SIGWINCH
                     73: /*
                     74:  * "Window" change handler
                     75:  */
                     76:        /* ARGSUSED*/
                     77:        public RETSIGTYPE
                     78: winch(type)
                     79:        int type;
                     80: {
                     81:        sigs |= S_WINCH;
                     82: }
                     83: #else
                     84: #ifdef SIGWIND
                     85: /*
                     86:  * "Window" change handler
                     87:  */
                     88:        /* ARGSUSED*/
                     89:        public RETSIGTYPE
                     90: winch(type)
                     91:        int type;
                     92: {
                     93:        sigs |= S_WINCH;
                     94: }
                     95: #endif
                     96: #endif
                     97:
1.4       millert    98: #if MSDOS_COMPILER==WIN32C
                     99: /*
                    100:  * Handle CTRL-C and CTRL-BREAK keys.
                    101:  */
                    102: #include "windows.h"
                    103:
                    104:        static BOOL WINAPI
                    105: wbreak_handler(dwCtrlType)
                    106:        DWORD dwCtrlType;
                    107: {
                    108:        switch (dwCtrlType)
                    109:        {
                    110:        case CTRL_C_EVENT:
                    111:        case CTRL_BREAK_EVENT:
                    112:                sigs |= S_INTERRUPT;
                    113:                return (TRUE);
                    114:        default:
                    115:                break;
                    116:        }
                    117:        return (FALSE);
                    118: }
                    119: #endif
                    120:
1.1       etheisen  121: /*
                    122:  * Set up the signal handlers.
                    123:  */
                    124:        public void
                    125: init_signals(on)
                    126:        int on;
                    127: {
                    128:        if (on)
                    129:        {
                    130:                /*
                    131:                 * Set signal handlers.
                    132:                 */
1.4       millert   133:                (void) LSIGNAL(SIGINT, u_interrupt);
                    134: #if MSDOS_COMPILER==WIN32C
                    135:                SetConsoleCtrlHandler(wbreak_handler, TRUE);
                    136: #endif
1.1       etheisen  137: #ifdef SIGTSTP
1.4       millert   138:                (void) LSIGNAL(SIGTSTP, stop);
1.1       etheisen  139: #endif
                    140: #ifdef SIGWINCH
1.4       millert   141:                (void) LSIGNAL(SIGWINCH, winch);
1.7       shadchin  142: #endif
1.1       etheisen  143: #ifdef SIGWIND
1.4       millert   144:                (void) LSIGNAL(SIGWIND, winch);
                    145: #endif
                    146: #ifdef SIGQUIT
                    147:                (void) LSIGNAL(SIGQUIT, SIG_IGN);
1.1       etheisen  148: #endif
                    149:        } else
                    150:        {
                    151:                /*
                    152:                 * Restore signals to defaults.
                    153:                 */
1.4       millert   154:                (void) LSIGNAL(SIGINT, SIG_DFL);
                    155: #if MSDOS_COMPILER==WIN32C
                    156:                SetConsoleCtrlHandler(wbreak_handler, FALSE);
                    157: #endif
1.1       etheisen  158: #ifdef SIGTSTP
1.4       millert   159:                (void) LSIGNAL(SIGTSTP, SIG_DFL);
1.1       etheisen  160: #endif
                    161: #ifdef SIGWINCH
1.4       millert   162:                (void) LSIGNAL(SIGWINCH, SIG_IGN);
1.1       etheisen  163: #endif
                    164: #ifdef SIGWIND
1.4       millert   165:                (void) LSIGNAL(SIGWIND, SIG_IGN);
                    166: #endif
                    167: #ifdef SIGQUIT
                    168:                (void) LSIGNAL(SIGQUIT, SIG_DFL);
1.1       etheisen  169: #endif
                    170:        }
                    171: }
                    172:
                    173: /*
                    174:  * Process any signals we have received.
                    175:  * A received signal cause a bit to be set in "sigs".
                    176:  */
                    177:        public void
                    178: psignals()
                    179: {
1.4       millert   180:        register int tsignals;
1.1       etheisen  181:
                    182:        if ((tsignals = sigs) == 0)
                    183:                return;
                    184:        sigs = 0;
                    185:
                    186: #ifdef SIGTSTP
                    187:        if (tsignals & S_STOP)
                    188:        {
                    189:                /*
                    190:                 * Clean up the terminal.
                    191:                 */
                    192: #ifdef SIGTTOU
1.4       millert   193:                LSIGNAL(SIGTTOU, SIG_IGN);
1.1       etheisen  194: #endif
                    195:                clear_bot();
                    196:                deinit();
                    197:                flush();
                    198:                raw_mode(0);
                    199: #ifdef SIGTTOU
1.4       millert   200:                LSIGNAL(SIGTTOU, SIG_DFL);
1.1       etheisen  201: #endif
1.4       millert   202:                LSIGNAL(SIGTSTP, SIG_DFL);
1.1       etheisen  203:                kill(getpid(), SIGTSTP);
                    204:                /*
                    205:                 * ... Bye bye. ...
                    206:                 * Hopefully we'll be back later and resume here...
                    207:                 * Reset the terminal and arrange to repaint the
                    208:                 * screen when we get back to the main command loop.
                    209:                 */
1.4       millert   210:                LSIGNAL(SIGTSTP, stop);
1.1       etheisen  211:                raw_mode(1);
                    212:                init();
                    213:                screen_trashed = 1;
                    214:                tsignals |= S_WINCH;
                    215:        }
                    216: #endif
                    217: #ifdef S_WINCH
                    218:        if (tsignals & S_WINCH)
                    219:        {
                    220:                int old_width, old_height;
                    221:                /*
                    222:                 * Re-execute scrsize() to read the new window size.
                    223:                 */
                    224:                old_width = sc_width;
                    225:                old_height = sc_height;
                    226:                get_term();
                    227:                if (sc_width != old_width || sc_height != old_height)
                    228:                {
                    229:                        wscroll = (sc_height + 1) / 2;
1.7       shadchin  230:                        calc_jump_sline();
                    231:                        calc_shift_count();
1.1       etheisen  232:                        screen_trashed = 1;
                    233:                }
                    234:        }
                    235: #endif
                    236:        if (tsignals & S_INTERRUPT)
                    237:        {
1.8     ! millert   238:                bell();
1.7       shadchin  239:                if (quit_on_intr)
                    240:                        quit(QUIT_INTERRUPT);
1.1       etheisen  241:        }
1.5       millert   242: }
                    243:
                    244: /*
                    245:  * Custom version of signal() that causes syscalls to be interrupted.
                    246:  */
                    247:        public void
                    248: (*lsignal(s, a))()
                    249:        int s;
                    250:        void (*a) ();
                    251: {
                    252:        struct sigaction sa, osa;
                    253:
                    254:        sa.sa_handler = a;
                    255:        sigemptyset(&sa.sa_mask);
                    256:        sa.sa_flags = 0;                /* don't restart system calls */
                    257:        if (sigaction(s, &sa, &osa) != 0)
                    258:                return (SIG_ERR);
                    259:        return (osa.sa_handler);
1.1       etheisen  260: }