diff options
author | etheisen <etheisen@cvs.openbsd.org> | 1996-09-21 05:39:47 +0000 |
---|---|---|
committer | etheisen <etheisen@cvs.openbsd.org> | 1996-09-21 05:39:47 +0000 |
commit | 47d3895c0565680e9e7eba725be0896bfd06ce11 (patch) | |
tree | 921c411da39dc3da0c9f04e1732558983f372819 /usr.bin/less/signal.c | |
parent | a2e06afb07d9a651364258a3d25e37f99d1dae46 (diff) |
Import of unmolested less-290.
Diffstat (limited to 'usr.bin/less/signal.c')
-rw-r--r-- | usr.bin/less/signal.c | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/usr.bin/less/signal.c b/usr.bin/less/signal.c new file mode 100644 index 00000000000..9cbafa064b6 --- /dev/null +++ b/usr.bin/less/signal.c @@ -0,0 +1,242 @@ +/* + * Copyright (c) 1984,1985,1989,1994,1995 Mark Nudelman + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice in the documentation and/or other materials provided with + * the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +/* + * Routines dealing with signals. + * + * A signal usually merely causes a bit to be set in the "signals" word. + * At some convenient time, the mainline code checks to see if any + * signals need processing by calling psignal(). + * If we happen to be reading from a file [in iread()] at the time + * the signal is received, we call intread to interrupt the iread. + */ + +#include "less.h" +#include <signal.h> + +/* + * "sigs" contains bits indicating signals which need to be processed. + */ +public int sigs; + +extern int sc_width, sc_height; +extern int screen_trashed; +extern int lnloop; +extern int linenums; +extern int wscroll; +extern int reading; + +/* + * Interrupt signal handler. + */ + /* ARGSUSED*/ + static RETSIGTYPE +u_interrupt(type) + int type; +{ +#if OS2 + SIGNAL(SIGINT, SIG_ACK); +#endif + SIGNAL(SIGINT, u_interrupt); + sigs |= S_INTERRUPT; + if (reading) + intread(); +} + +#ifdef SIGTSTP +/* + * "Stop" (^Z) signal handler. + */ + /* ARGSUSED*/ + static RETSIGTYPE +stop(type) + int type; +{ + SIGNAL(SIGTSTP, stop); + sigs |= S_STOP; + if (reading) + intread(); +} +#endif + +#ifdef SIGWINCH +/* + * "Window" change handler + */ + /* ARGSUSED*/ + public RETSIGTYPE +winch(type) + int type; +{ + SIGNAL(SIGWINCH, winch); + sigs |= S_WINCH; + if (reading) + intread(); +} +#else +#ifdef SIGWIND +/* + * "Window" change handler + */ + /* ARGSUSED*/ + public RETSIGTYPE +winch(type) + int type; +{ + SIGNAL(SIGWIND, winch); + sigs |= S_WINCH; + if (reading) + intread(); +} +#endif +#endif + +/* + * Set up the signal handlers. + */ + public void +init_signals(on) + int on; +{ + if (on) + { + /* + * Set signal handlers. + */ + (void) SIGNAL(SIGINT, u_interrupt); +#ifdef SIGTSTP + (void) SIGNAL(SIGTSTP, stop); +#endif +#ifdef SIGWINCH + (void) SIGNAL(SIGWINCH, winch); +#else +#ifdef SIGWIND + (void) SIGNAL(SIGWIND, winch); +#endif +#endif + } else + { + /* + * Restore signals to defaults. + */ + (void) SIGNAL(SIGINT, SIG_DFL); +#ifdef SIGTSTP + (void) SIGNAL(SIGTSTP, SIG_DFL); +#endif +#ifdef SIGWINCH + (void) SIGNAL(SIGWINCH, SIG_IGN); +#endif +#ifdef SIGWIND + (void) SIGNAL(SIGWIND, SIG_IGN); +#endif + } +} + +/* + * Process any signals we have received. + * A received signal cause a bit to be set in "sigs". + */ + public void +psignals() +{ + register int tsignals; + + if ((tsignals = sigs) == 0) + return; + sigs = 0; + +#ifdef SIGTSTP + if (tsignals & S_STOP) + { + /* + * Clean up the terminal. + */ +#ifdef SIGTTOU + SIGNAL(SIGTTOU, SIG_IGN); +#endif + clear_bot(); + deinit(); + flush(); + raw_mode(0); +#ifdef SIGTTOU + SIGNAL(SIGTTOU, SIG_DFL); +#endif + SIGNAL(SIGTSTP, SIG_DFL); + kill(getpid(), SIGTSTP); + /* + * ... Bye bye. ... + * Hopefully we'll be back later and resume here... + * Reset the terminal and arrange to repaint the + * screen when we get back to the main command loop. + */ + SIGNAL(SIGTSTP, stop); + raw_mode(1); + init(); + screen_trashed = 1; + tsignals |= S_WINCH; + } +#endif +#ifdef S_WINCH + if (tsignals & S_WINCH) + { + int old_width, old_height; + /* + * Re-execute scrsize() to read the new window size. + */ + old_width = sc_width; + old_height = sc_height; + get_term(); + if (sc_width != old_width || sc_height != old_height) + { + wscroll = (sc_height + 1) / 2; + screen_trashed = 1; + } + } +#endif + if (tsignals & S_INTERRUPT) + { + bell(); + /* + * {{ You may wish to replace the bell() with + * error("Interrupt", NULL_PARG); }} + */ + + /* + * If we were interrupted while in the "calculating + * line numbers" loop, turn off line numbers. + */ + if (lnloop) + { + lnloop = 0; + if (linenums == 2) + screen_trashed = 1; + linenums = 0; + error("Line numbers turned off", NULL_PARG); + } + + } +} |