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