home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume16 / less5 / part02 / signal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-09-22  |  3.4 KB  |  213 lines

  1. /*
  2.  * Routines dealing with signals.
  3.  *
  4.  * A signal usually merely causes a bit to be set in the "signals" word.
  5.  * At some convenient time, the mainline code checks to see if any
  6.  * signals need processing by calling psignal().
  7.  * If we happen to be reading from a file [in iread()] at the time
  8.  * the signal is received, we call intread to interrupt the iread.
  9.  */
  10.  
  11. #include "less.h"
  12. #include <signal.h>
  13.  
  14. /*
  15.  * "sigs" contains bits indicating signals which need to be processed.
  16.  */
  17. public int sigs;
  18.  
  19. #define    S_INTERRUPT    01
  20. #ifdef SIGTSTP
  21. #define    S_STOP        02
  22. #endif
  23. #if defined(SIGWINCH) || defined(SIGWIND)
  24. #define S_WINCH        04
  25. #endif
  26.  
  27. extern int sc_width, sc_height;
  28. extern int screen_trashed;
  29. extern int lnloop;
  30. extern int linenums;
  31. extern int scroll;
  32. extern int reading;
  33.  
  34. /*
  35.  * Interrupt signal handler.
  36.  */
  37.     static HANDLER
  38. interrupt()
  39. {
  40.     SIGNAL(SIGINT, interrupt);
  41.     sigs |= S_INTERRUPT;
  42.     if (reading)
  43.         intread();
  44. }
  45.  
  46. #ifdef SIGTSTP
  47. /*
  48.  * "Stop" (^Z) signal handler.
  49.  */
  50.     static HANDLER
  51. stop()
  52. {
  53.     SIGNAL(SIGTSTP, stop);
  54.     sigs |= S_STOP;
  55.     if (reading)
  56.         intread();
  57. }
  58. #endif
  59.  
  60. #ifdef SIGWINCH
  61. /*
  62.  * "Window" change handler
  63.  */
  64.     public HANDLER
  65. winch()
  66. {
  67.     SIGNAL(SIGWINCH, winch);
  68.     sigs |= S_WINCH;
  69.     if (reading)
  70.         intread();
  71. }
  72. #else
  73. #ifdef SIGWIND
  74. /*
  75.  * "Window" change handler
  76.  */
  77.     public HANDLER
  78. winch()
  79. {
  80.     SIGNAL(SIGWIND, winch);
  81.     sigs |= S_WINCH;
  82.     if (reading)
  83.         intread();
  84. }
  85. #endif
  86. #endif
  87.  
  88. /*
  89.  * Set up the signal handlers.
  90.  */
  91.     public void
  92. init_signals(on)
  93.     int on;
  94. {
  95.     if (on)
  96.     {
  97.         /*
  98.          * Set signal handlers.
  99.          */
  100.         (void) SIGNAL(SIGINT, interrupt);
  101. #ifdef SIGTSTP
  102.         (void) SIGNAL(SIGTSTP, stop);
  103. #endif
  104. #ifdef SIGWINCH
  105.         (void) SIGNAL(SIGWINCH, winch);
  106. #else
  107. #ifdef SIGWIND
  108.         (void) SIGNAL(SIGWIND, winch);
  109. #endif
  110. #endif
  111.     } else
  112.     {
  113.         /*
  114.          * Restore signals to defaults.
  115.          */
  116.         (void) SIGNAL(SIGINT, SIG_DFL);
  117. #ifdef SIGTSTP
  118.         (void) SIGNAL(SIGTSTP, SIG_DFL);
  119. #endif
  120. #ifdef SIGWINCH
  121.         (void) SIGNAL(SIGWINCH, SIG_IGN);
  122. #endif
  123. #ifdef SIGWIND
  124.         (void) SIGNAL(SIGWIND, SIG_IGN);
  125. #endif
  126.     }
  127. }
  128.  
  129. /*
  130.  * Process any signals we have received.
  131.  * A received signal cause a bit to be set in "sigs".
  132.  */
  133.     public int
  134. psignals()
  135. {
  136.     register int tsignals;
  137.  
  138.     if ((tsignals = sigs) == 0)
  139.         return (0);
  140.     sigs = 0;
  141.  
  142. #ifdef S_WINCH
  143.     if (tsignals & S_WINCH)
  144.     {
  145.         int old_width, old_height;
  146.         /*
  147.          * Re-execute get_term() to read the new window size.
  148.          */
  149.         old_width = sc_width;
  150.         old_height = sc_height;
  151.         get_term();
  152.         if (sc_width != old_width || sc_height != old_height)
  153.         {
  154.             scroll = (sc_height + 1) / 2;
  155.             screen_trashed = 1;
  156.         }
  157.     }
  158. #endif
  159. #ifdef SIGTSTP
  160.     if (tsignals & S_STOP)
  161.     {
  162.         /*
  163.          * Clean up the terminal.
  164.          */
  165. #ifdef SIGTTOU
  166.         SIGNAL(SIGTTOU, SIG_IGN);
  167. #endif
  168.         lower_left();
  169.         clear_eol();
  170.         deinit();
  171.         flush();
  172.         raw_mode(0);
  173. #ifdef SIGTTOU
  174.         SIGNAL(SIGTTOU, SIG_DFL);
  175. #endif
  176.         SIGNAL(SIGTSTP, SIG_DFL);
  177.         kill(getpid(), SIGTSTP);
  178.         /*
  179.          * ... Bye bye. ...
  180.          * Hopefully we'll be back later and resume here...
  181.          * Reset the terminal and arrange to repaint the
  182.          * screen when we get back to the main command loop.
  183.          */
  184.         SIGNAL(SIGTSTP, stop);
  185.         raw_mode(1);
  186.         init();
  187.         screen_trashed = 1;
  188.     }
  189. #endif
  190.     if (tsignals & S_INTERRUPT)
  191.     {
  192.         bell();
  193.         /*
  194.          * {{ You may wish to replace the bell() with 
  195.          *    error("Interrupt"); }}
  196.          */
  197.  
  198.         /*
  199.          * If we were interrupted while in the "calculating 
  200.          * line numbers" loop, turn off line numbers.
  201.          */
  202.         if (lnloop)
  203.         {
  204.             lnloop = 0;
  205.             linenums = 0;
  206.             error("Line numbers turned off");
  207.         }
  208.  
  209.     }
  210.  
  211.     return (1);
  212. }
  213.