home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 036 / less232.zip / SIGNAL.C < prev    next >
C/C++ Source or Header  |  1994-09-22  |  5KB  |  247 lines

  1. /*
  2.  * Copyright (c) 1984,1985,1989,1994  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.     SIGNAL(SIGINT, u_interrupt);
  62.     sigs |= S_INTERRUPT;
  63.     if (reading)
  64.         intread();
  65. }
  66.  
  67.     public void
  68. fake_interrupt()
  69. {
  70.     sigs |= S_INTERRUPT;
  71. }
  72.  
  73. #ifdef SIGTSTP
  74. /*
  75.  * "Stop" (^Z) signal handler.
  76.  */
  77.     /* ARGSUSED*/
  78.     static RETSIGTYPE
  79. stop(type)
  80.     int type;
  81. {
  82.     SIGNAL(SIGTSTP, stop);
  83.     sigs |= S_STOP;
  84.     if (reading)
  85.         intread();
  86. }
  87. #endif
  88.  
  89. #ifdef SIGWINCH
  90. /*
  91.  * "Window" change handler
  92.  */
  93.     /* ARGSUSED*/
  94.     public RETSIGTYPE
  95. winch(type)
  96.     int type;
  97. {
  98.     SIGNAL(SIGWINCH, winch);
  99.     sigs |= S_WINCH;
  100.     if (reading)
  101.         intread();
  102. }
  103. #else
  104. #ifdef SIGWIND
  105. /*
  106.  * "Window" change handler
  107.  */
  108.     /* ARGSUSED*/
  109.     public RETSIGTYPE
  110. winch(type)
  111.     int type;
  112. {
  113.     SIGNAL(SIGWIND, winch);
  114.     sigs |= S_WINCH;
  115.     if (reading)
  116.         intread();
  117. }
  118. #endif
  119. #endif
  120.  
  121. /*
  122.  * Set up the signal handlers.
  123.  */
  124.     public void
  125. init_signals(on)
  126.     int on;
  127. {
  128.     if (on)
  129.     {
  130.         /*
  131.          * Set signal handlers.
  132.          */
  133.         (void) SIGNAL(SIGINT, u_interrupt);
  134. #ifdef SIGTSTP
  135.         (void) SIGNAL(SIGTSTP, stop);
  136. #endif
  137. #ifdef SIGWINCH
  138.         (void) SIGNAL(SIGWINCH, winch);
  139. #else
  140. #ifdef SIGWIND
  141.         (void) SIGNAL(SIGWIND, winch);
  142. #endif
  143. #endif
  144.     } else
  145.     {
  146.         /*
  147.          * Restore signals to defaults.
  148.          */
  149.         (void) SIGNAL(SIGINT, SIG_DFL);
  150. #ifdef SIGTSTP
  151.         (void) SIGNAL(SIGTSTP, SIG_DFL);
  152. #endif
  153. #ifdef SIGWINCH
  154.         (void) SIGNAL(SIGWINCH, SIG_IGN);
  155. #endif
  156. #ifdef SIGWIND
  157.         (void) SIGNAL(SIGWIND, SIG_IGN);
  158. #endif
  159.     }
  160. }
  161.  
  162. /*
  163.  * Process any signals we have received.
  164.  * A received signal cause a bit to be set in "sigs".
  165.  */
  166.     public void
  167. psignals()
  168. {
  169.     register int tsignals;
  170.  
  171.     if ((tsignals = sigs) == 0)
  172.         return;
  173.     sigs = 0;
  174.  
  175. #ifdef SIGTSTP
  176.     if (tsignals & S_STOP)
  177.     {
  178.         /*
  179.          * Clean up the terminal.
  180.          */
  181. #ifdef SIGTTOU
  182.         SIGNAL(SIGTTOU, SIG_IGN);
  183. #endif
  184.         clear_bot();
  185.         deinit();
  186.         flush();
  187.         raw_mode(0);
  188. #ifdef SIGTTOU
  189.         SIGNAL(SIGTTOU, SIG_DFL);
  190. #endif
  191.         SIGNAL(SIGTSTP, SIG_DFL);
  192.         kill(getpid(), SIGTSTP);
  193.         /*
  194.          * ... Bye bye. ...
  195.          * Hopefully we'll be back later and resume here...
  196.          * Reset the terminal and arrange to repaint the
  197.          * screen when we get back to the main command loop.
  198.          */
  199.         SIGNAL(SIGTSTP, stop);
  200.         raw_mode(1);
  201.         init();
  202.         screen_trashed = 1;
  203.         tsignals |= S_WINCH;
  204.     }
  205. #endif
  206. #ifdef S_WINCH
  207.     if (tsignals & S_WINCH)
  208.     {
  209.         int old_width, old_height;
  210.         /*
  211.          * Re-execute scrsize() to read the new window size.
  212.          */
  213.         old_width = sc_width;
  214.         old_height = sc_height;
  215.         scrsize();
  216.         pos_init();
  217.         if (sc_width != old_width || sc_height != old_height)
  218.         {
  219.             wscroll = (sc_height + 1) / 2;
  220.             screen_trashed = 1;
  221.         }
  222.     }
  223. #endif
  224.     if (tsignals & S_INTERRUPT)
  225.     {
  226.         bell();
  227.         /*
  228.          * {{ You may wish to replace the bell() with 
  229.          *    error("Interrupt", NULL_PARG); }}
  230.          */
  231.  
  232.         /*
  233.          * If we were interrupted while in the "calculating 
  234.          * line numbers" loop, turn off line numbers.
  235.          */
  236.         if (lnloop)
  237.         {
  238.             lnloop = 0;
  239.             if (linenums == 2)
  240.                 screen_trashed = 1;
  241.             linenums = 0;
  242.             error("Line numbers turned off", NULL_PARG);
  243.         }
  244.  
  245.     }
  246. }
  247.