home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / less-321-src.tgz / tar.out / fsf / less / signal.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  243 lines

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