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

1.1       etheisen    1: /*
1.9       shadchin    2:  * Copyright (C) 1984-2012  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.9       shadchin    7:  * For more information, see the README file.
1.1       etheisen    8:  */
1.10    ! nicm        9: /*
        !            10:  * Modified for use with illumos.
        !            11:  * Copyright 2015 Garrett D'Amore <garrett@damore.org>
        !            12:  */
1.1       etheisen   13:
                     14: /*
                     15:  * Routines dealing with signals.
                     16:  *
                     17:  * A signal usually merely causes a bit to be set in the "signals" word.
                     18:  * At some convenient time, the mainline code checks to see if any
                     19:  * signals need processing by calling psignal().
                     20:  */
                     21:
                     22: #include "less.h"
                     23: #include <signal.h>
                     24:
                     25: /*
                     26:  * "sigs" contains bits indicating signals which need to be processed.
                     27:  */
1.10    ! nicm       28: volatile sig_atomic_t sigs;
1.1       etheisen   29:
                     30: extern int sc_width, sc_height;
                     31: extern int screen_trashed;
                     32: extern int linenums;
                     33: extern int wscroll;
1.7       shadchin   34: extern int quit_on_intr;
                     35: extern long jump_sline_fraction;
1.1       etheisen   36:
                     37: /*
                     38:  * Interrupt signal handler.
                     39:  */
1.10    ! nicm       40: /* ARGSUSED */
        !            41: static void
        !            42: u_interrupt(int type)
        !            43: {
1.1       etheisen   44:        sigs |= S_INTERRUPT;
                     45: }
                     46:
                     47: /*
                     48:  * "Stop" (^Z) signal handler.
                     49:  */
1.10    ! nicm       50: /* ARGSUSED */
        !            51: static void
        !            52: stop(int type)
1.1       etheisen   53: {
                     54:        sigs |= S_STOP;
                     55: }
                     56:
                     57: /*
                     58:  * "Window" change handler
                     59:  */
1.10    ! nicm       60: /* ARGSUSED */
        !            61: void
        !            62: sigwinch(int type)
1.1       etheisen   63: {
                     64:        sigs |= S_WINCH;
                     65: }
1.4       millert    66:
1.1       etheisen   67: /*
                     68:  * Set up the signal handlers.
                     69:  */
1.10    ! nicm       70: void
        !            71: init_signals(int on)
1.1       etheisen   72: {
1.10    ! nicm       73:        if (on) {
1.1       etheisen   74:                /*
                     75:                 * Set signal handlers.
                     76:                 */
1.4       millert    77:                (void) LSIGNAL(SIGINT, u_interrupt);
                     78:                (void) LSIGNAL(SIGTSTP, stop);
1.10    ! nicm       79:                (void) LSIGNAL(SIGWINCH, sigwinch);
1.4       millert    80:                (void) LSIGNAL(SIGQUIT, SIG_IGN);
1.10    ! nicm       81:        } else {
1.1       etheisen   82:                /*
                     83:                 * Restore signals to defaults.
                     84:                 */
1.4       millert    85:                (void) LSIGNAL(SIGINT, SIG_DFL);
                     86:                (void) LSIGNAL(SIGTSTP, SIG_DFL);
                     87:                (void) LSIGNAL(SIGWINCH, SIG_IGN);
                     88:                (void) LSIGNAL(SIGQUIT, SIG_DFL);
1.1       etheisen   89:        }
                     90: }
                     91:
                     92: /*
                     93:  * Process any signals we have received.
                     94:  * A received signal cause a bit to be set in "sigs".
                     95:  */
1.10    ! nicm       96: void
        !            97: psignals(void)
1.1       etheisen   98: {
1.4       millert    99:        register int tsignals;
1.1       etheisen  100:
                    101:        if ((tsignals = sigs) == 0)
                    102:                return;
                    103:        sigs = 0;
                    104:
1.10    ! nicm      105:        if (tsignals & S_STOP) {
1.1       etheisen  106:                /*
                    107:                 * Clean up the terminal.
                    108:                 */
1.4       millert   109:                LSIGNAL(SIGTTOU, SIG_IGN);
1.1       etheisen  110:                clear_bot();
                    111:                deinit();
                    112:                flush();
                    113:                raw_mode(0);
1.4       millert   114:                LSIGNAL(SIGTTOU, SIG_DFL);
                    115:                LSIGNAL(SIGTSTP, SIG_DFL);
1.1       etheisen  116:                kill(getpid(), SIGTSTP);
                    117:                /*
                    118:                 * ... Bye bye. ...
                    119:                 * Hopefully we'll be back later and resume here...
                    120:                 * Reset the terminal and arrange to repaint the
                    121:                 * screen when we get back to the main command loop.
                    122:                 */
1.4       millert   123:                LSIGNAL(SIGTSTP, stop);
1.1       etheisen  124:                raw_mode(1);
                    125:                init();
                    126:                screen_trashed = 1;
                    127:                tsignals |= S_WINCH;
                    128:        }
1.10    ! nicm      129:        if (tsignals & S_WINCH) {
1.1       etheisen  130:                int old_width, old_height;
                    131:                /*
                    132:                 * Re-execute scrsize() to read the new window size.
                    133:                 */
                    134:                old_width = sc_width;
                    135:                old_height = sc_height;
                    136:                get_term();
1.10    ! nicm      137:                if (sc_width != old_width || sc_height != old_height) {
1.1       etheisen  138:                        wscroll = (sc_height + 1) / 2;
1.7       shadchin  139:                        calc_jump_sline();
                    140:                        calc_shift_count();
1.1       etheisen  141:                        screen_trashed = 1;
                    142:                }
                    143:        }
1.10    ! nicm      144:        if (tsignals & S_INTERRUPT) {
        !           145:                ring_bell();
1.7       shadchin  146:                if (quit_on_intr)
                    147:                        quit(QUIT_INTERRUPT);
1.1       etheisen  148:        }
1.5       millert   149: }
                    150:
                    151: /*
                    152:  * Custom version of signal() that causes syscalls to be interrupted.
                    153:  */
1.10    ! nicm      154: void *
        !           155: lsignal(int s, void (*a)(int))
1.5       millert   156: {
                    157:        struct sigaction sa, osa;
                    158:
                    159:        sa.sa_handler = a;
                    160:        sigemptyset(&sa.sa_mask);
1.10    ! nicm      161:        sa.sa_flags = 0;                /* don't restart system calls */
1.5       millert   162:        if (sigaction(s, &sa, &osa) != 0)
                    163:                return (SIG_ERR);
                    164:        return (osa.sa_handler);
1.1       etheisen  165: }