home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / more / signal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-03  |  4.9 KB  |  221 lines

  1. /*
  2.  * Copyright (c) 1988 Mark Nudleman
  3.  * Copyright (c) 1988 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  *    This product includes software developed by the University of
  17.  *    California, Berkeley and its contributors.
  18.  * 4. Neither the name of the University nor the names of its contributors
  19.  *    may be used to endorse or promote products derived from this software
  20.  *    without specific prior written permission.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  */
  34.  
  35. #ifndef lint
  36. static char sccsid[] = "@(#)signal.c    5.8 (Berkeley) 3/1/91";
  37. #endif /* not lint */
  38.  
  39. /*
  40.  * Routines dealing with signals.
  41.  *
  42.  * A signal usually merely causes a bit to be set in the "signals" word.
  43.  * At some convenient time, the mainline code checks to see if any
  44.  * signals need processing by calling psignal().
  45.  * If we happen to be reading from a file [in iread()] at the time
  46.  * the signal is received, we call intread to interrupt the iread.
  47.  */
  48.  
  49. #include <less.h>
  50. #include <signal.h>
  51.  
  52. /*
  53.  * "sigs" contains bits indicating signals which need to be processed.
  54.  */
  55. int sigs;
  56.  
  57. #ifdef SIGTSTP
  58. #define    S_STOP        02
  59. #endif
  60. #if defined(SIGWINCH) || defined(SIGWIND)
  61. #define S_WINCH        04
  62. #endif
  63.  
  64. extern int sc_width, sc_height;
  65. extern int screen_trashed;
  66. extern int lnloop;
  67. extern int linenums;
  68. extern int scroll;
  69. extern int reading;
  70.  
  71. #ifdef SIGTSTP
  72. /*
  73.  * "Stop" (^Z) signal handler.
  74.  */
  75. static void
  76. stop()
  77. {
  78.     (void)signal(SIGTSTP, stop);
  79.     sigs |= S_STOP;
  80.     if (reading)
  81.         intread();
  82. }
  83. #endif
  84.  
  85. #ifdef SIGWINCH
  86. /*
  87.  * "Window" change handler
  88.  */
  89. void
  90. winch()
  91. {
  92.     (void)signal(SIGWINCH, winch);
  93.     sigs |= S_WINCH;
  94.     if (reading)
  95.         intread();
  96. }
  97. #else
  98. #ifdef SIGWIND
  99. /*
  100.  * "Window" change handler
  101.  */
  102. winch()
  103. {
  104.     (void)signal(SIGWIND, winch);
  105.     sigs |= S_WINCH;
  106.     if (reading)
  107.         intread();
  108. }
  109. #endif
  110. #endif
  111.  
  112. static void
  113. purgeandquit()
  114. {
  115.  
  116.     purge();    /* purge buffered output */
  117.     quit();
  118. }
  119.  
  120. /*
  121.  * Set up the signal handlers.
  122.  */
  123. init_signals(on)
  124.     int on;
  125. {
  126.     if (on)
  127.     {
  128.         /*
  129.          * Set signal handlers.
  130.          */
  131.         (void)signal(SIGINT, purgeandquit);
  132. #ifdef SIGTSTP
  133.         (void)signal(SIGTSTP, stop);
  134. #endif
  135. #ifdef SIGWINCH
  136.         (void)signal(SIGWINCH, winch);
  137. #else
  138. #ifdef SIGWIND
  139.         (void)signal(SIGWIND, winch);
  140. #endif
  141. #endif
  142.     } else
  143.     {
  144.         /*
  145.          * Restore signals to defaults.
  146.          */
  147.         (void)signal(SIGINT, SIG_DFL);
  148. #ifdef SIGTSTP
  149.         (void)signal(SIGTSTP, SIG_DFL);
  150. #endif
  151. #ifdef SIGWINCH
  152.         (void)signal(SIGWINCH, SIG_IGN);
  153. #endif
  154. #ifdef SIGWIND
  155.         (void)signal(SIGWIND, SIG_IGN);
  156. #endif
  157.     }
  158. }
  159.  
  160. /*
  161.  * Process any signals we have received.
  162.  * A received signal cause a bit to be set in "sigs".
  163.  */
  164. psignals()
  165. {
  166.     register int tsignals;
  167.  
  168.     if ((tsignals = sigs) == 0)
  169.         return;
  170.     sigs = 0;
  171.  
  172. #ifdef S_WINCH
  173.     if (tsignals & S_WINCH)
  174.     {
  175.         int old_width, old_height;
  176.         /*
  177.          * Re-execute get_term() to read the new window size.
  178.          */
  179.         old_width = sc_width;
  180.         old_height = sc_height;
  181.         get_term();
  182.         if (sc_width != old_width || sc_height != old_height)
  183.         {
  184.             scroll = (sc_height + 1) / 2;
  185.             screen_trashed = 1;
  186.         }
  187.     }
  188. #endif
  189. #ifdef SIGTSTP
  190.     if (tsignals & S_STOP)
  191.     {
  192.         /*
  193.          * Clean up the terminal.
  194.          */
  195. #ifdef SIGTTOU
  196.         (void)signal(SIGTTOU, SIG_IGN);
  197. #endif
  198.         lower_left();
  199.         clear_eol();
  200.         deinit();
  201.         (void)flush();
  202.         raw_mode(0);
  203. #ifdef SIGTTOU
  204.         (void)signal(SIGTTOU, SIG_DFL);
  205. #endif
  206.         (void)signal(SIGTSTP, SIG_DFL);
  207.         (void)kill(getpid(), SIGTSTP);
  208.         /*
  209.          * ... Bye bye. ...
  210.          * Hopefully we'll be back later and resume here...
  211.          * Reset the terminal and arrange to repaint the
  212.          * screen when we get back to the main command loop.
  213.          */
  214.         (void)signal(SIGTSTP, stop);
  215.         raw_mode(1);
  216.         init();
  217.         screen_trashed = 1;
  218.     }
  219. #endif
  220. }
  221.