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

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