home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / LESS177.ZIP / src / signal.c < prev    next >
C/C++ Source or Header  |  1992-07-18  |  4KB  |  255 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. #if OS2
  20. public int os2sigs;
  21. #endif
  22.  
  23. #define    S_INTERRUPT    01
  24. #ifdef SIGTSTP
  25. #define    S_STOP        02
  26. #endif
  27. #if defined(SIGWINCH) || defined(SIGWIND)
  28. #define S_WINCH        04
  29. #endif
  30.  
  31. extern int sc_width, sc_height;
  32. extern int swindow;
  33. extern int screen_trashed;
  34. extern int lnloop;
  35. extern int linenums;
  36. extern int scroll;
  37. extern int reading;
  38.  
  39. /*
  40.  * Interrupt signal handler.
  41.  */
  42.     /* ARGSUSED*/
  43.     static HANDLER
  44. u_interrupt(type)
  45.     int type;
  46. {
  47.     SIGNAL(SIGINT, u_interrupt);
  48.     sigs |= S_INTERRUPT;
  49.     if (reading)
  50.         intread();
  51. }
  52.  
  53.     public void
  54. fake_interrupt()
  55. {
  56.     sigs |= S_INTERRUPT;
  57. }
  58.  
  59. #ifdef SIGTSTP
  60. /*
  61.  * "Stop" (^Z) signal handler.
  62.  */
  63.     /* ARGSUSED*/
  64.     static HANDLER
  65. stop(type)
  66.     int type;
  67. {
  68.     SIGNAL(SIGTSTP, stop);
  69.     sigs |= S_STOP;
  70.     if (reading)
  71.         intread();
  72. }
  73. #endif
  74.  
  75. #ifdef SIGWINCH
  76. /*
  77.  * "Window" change handler
  78.  */
  79.     /* ARGSUSED*/
  80.     public HANDLER
  81. winch(type)
  82.     int type;
  83. {
  84.     SIGNAL(SIGWINCH, winch);
  85.     sigs |= S_WINCH;
  86.     if (reading)
  87.         intread();
  88. }
  89. #else
  90. #ifdef SIGWIND
  91. /*
  92.  * "Window" change handler
  93.  */
  94.     /* ARGSUSED*/
  95.     public HANDLER
  96. winch(type)
  97.     int type;
  98. {
  99.     SIGNAL(SIGWIND, winch);
  100.     sigs |= S_WINCH;
  101.     if (reading)
  102.         intread();
  103. }
  104. #endif
  105. #endif
  106.  
  107. /*
  108.  * Set up the signal handlers.
  109.  */
  110.     public void
  111. init_signals(on)
  112.     int on;
  113. {
  114.     if (on)
  115.     {
  116.         /*
  117.          * Set signal handlers.
  118.          */
  119.         (void) SIGNAL(SIGINT, u_interrupt);
  120. #ifdef SIGTSTP
  121.         (void) SIGNAL(SIGTSTP, stop);
  122. #endif
  123. #ifdef SIGWINCH
  124.         (void) SIGNAL(SIGWINCH, winch);
  125. #else
  126. #ifdef SIGWIND
  127.         (void) SIGNAL(SIGWIND, winch);
  128. #endif
  129. #endif
  130.     } else
  131.     {
  132.         /*
  133.          * Restore signals to defaults.
  134.          */
  135.         (void) SIGNAL(SIGINT, SIG_DFL);
  136. #ifdef SIGTSTP
  137.         (void) SIGNAL(SIGTSTP, SIG_DFL);
  138. #endif
  139. #ifdef SIGWINCH
  140.         (void) SIGNAL(SIGWINCH, SIG_IGN);
  141. #endif
  142. #ifdef SIGWIND
  143.         (void) SIGNAL(SIGWIND, SIG_IGN);
  144. #endif
  145.     }
  146. }
  147.  
  148. /*
  149.  * Process any signals we have received.
  150.  * A received signal cause a bit to be set in "sigs".
  151.  */
  152.     public void
  153. psignals()
  154. {
  155.     register int tsignals;
  156. #if OS2
  157.     if (os2sigs != 0)
  158.     {
  159.             int old_width, old_height;
  160.         os2sigs=0;
  161.  
  162.             /*
  163.          * Re-execute get_term() to read the new window size.
  164.          */
  165.         old_width = sc_width;
  166.         old_height = sc_height;
  167.         swindow = -1;
  168.         get_term();
  169.         if (sc_width != old_width || sc_height != old_height)
  170.         {
  171.                 scroll = (sc_height + 1) / 2;
  172.             screen_trashed = 1;
  173.             sigs=1;   /* sound the bell */
  174.             return;
  175.         }
  176.     }
  177. #endif
  178.  
  179.     if ((tsignals = sigs) == 0)
  180.         return;
  181.     sigs = 0;
  182.  
  183. #ifdef S_WINCH
  184.     if (tsignals & S_WINCH)
  185.     {
  186.         int old_width, old_height;
  187.         /*
  188.          * Re-execute get_term() to read the new window size.
  189.          */
  190.         old_width = sc_width;
  191.         old_height = sc_height;
  192.         swindow = -1;
  193.         get_term();
  194.         if (sc_width != old_width || sc_height != old_height)
  195.         {
  196.             scroll = (sc_height + 1) / 2;
  197.             screen_trashed = 1;
  198.         }
  199.     }
  200. #endif
  201. #ifdef SIGTSTP
  202.     if (tsignals & S_STOP)
  203.     {
  204.         /*
  205.          * Clean up the terminal.
  206.          */
  207. #ifdef SIGTTOU
  208.         SIGNAL(SIGTTOU, SIG_IGN);
  209. #endif
  210.         lower_left();
  211.         clear_eol();
  212.         deinit();
  213.         flush();
  214.         raw_mode(0);
  215. #ifdef SIGTTOU
  216.         SIGNAL(SIGTTOU, SIG_DFL);
  217. #endif
  218.         SIGNAL(SIGTSTP, SIG_DFL);
  219.         kill(getpid(), SIGTSTP);
  220.         /*
  221.          * ... Bye bye. ...
  222.          * Hopefully we'll be back later and resume here...
  223.          * Reset the terminal and arrange to repaint the
  224.          * screen when we get back to the main command loop.
  225.          */
  226.         SIGNAL(SIGTSTP, stop);
  227.         raw_mode(1);
  228.         init();
  229.         screen_trashed = 1;
  230.     }
  231. #endif
  232.     if (tsignals & S_INTERRUPT)
  233.     {
  234.         bell();
  235.         /*
  236.          * {{ You may wish to replace the bell() with 
  237.          *    error("Interrupt", NULL_PARG); }}
  238.          */
  239.  
  240.         /*
  241.          * If we were interrupted while in the "calculating 
  242.          * line numbers" loop, turn off line numbers.
  243.          */
  244.         if (lnloop)
  245.         {
  246.             lnloop = 0;
  247.             if (linenums == 2)
  248.                 screen_trashed = 1;
  249.             linenums = 0;
  250.             error("Line numbers turned off", NULL_PARG);
  251.         }
  252.  
  253.     }
  254. }
  255.