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

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