summaryrefslogtreecommitdiff
path: root/usr.bin/less/signal.c
diff options
context:
space:
mode:
authoretheisen <etheisen@cvs.openbsd.org>1996-09-21 05:39:47 +0000
committeretheisen <etheisen@cvs.openbsd.org>1996-09-21 05:39:47 +0000
commit47d3895c0565680e9e7eba725be0896bfd06ce11 (patch)
tree921c411da39dc3da0c9f04e1732558983f372819 /usr.bin/less/signal.c
parenta2e06afb07d9a651364258a3d25e37f99d1dae46 (diff)
Import of unmolested less-290.
Diffstat (limited to 'usr.bin/less/signal.c')
-rw-r--r--usr.bin/less/signal.c242
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);
+ }
+
+ }
+}