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