home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 6 File / 06-File.zip / less373.zip / signal.c < prev    next >
C/C++ Source or Header  |  2002-01-14  |  5KB  |  271 lines

  1. /*
  2.  * Copyright (C) 1984-2000  Mark Nudelman
  3.  *
  4.  * You may distribute under the terms of either the GNU General Public
  5.  * License or the Less License, as specified in the README file.
  6.  *
  7.  * For more information about less, or for information on how to 
  8.  * contact the author, see the README file.
  9.  */
  10.  
  11.  
  12. /*
  13.  * Routines dealing with signals.
  14.  *
  15.  * A signal usually merely causes a bit to be set in the "signals" word.
  16.  * At some convenient time, the mainline code checks to see if any
  17.  * signals need processing by calling psignal().
  18.  * If we happen to be reading from a file [in iread()] at the time
  19.  * the signal is received, we call intread to interrupt the iread.
  20.  */
  21.  
  22. #include "less.h"
  23. #include <signal.h>
  24.  
  25. /*
  26.  * "sigs" contains bits indicating signals which need to be processed.
  27.  */
  28. public int sigs;
  29.  
  30. extern int sc_width, sc_height;
  31. extern int screen_trashed;
  32. extern int lnloop;
  33. extern int linenums;
  34. extern int wscroll;
  35. extern int reading;
  36.  
  37. /*
  38.  * Interrupt signal handler.
  39.  */
  40.     /* ARGSUSED*/
  41.     static RETSIGTYPE
  42. u_interrupt(type)
  43.     int type;
  44. {
  45. #if OS2
  46.     LSIGNAL(SIGINT, SIG_ACK);
  47. #endif
  48.     LSIGNAL(SIGINT, u_interrupt);
  49.     sigs |= S_INTERRUPT;
  50. #if MSDOS_COMPILER==DJGPPC
  51.     /*
  52.      * If a keyboard has been hit, it must be Ctrl-C
  53.      * (as opposed to Ctrl-Break), so consume it.
  54.      * (Otherwise, Less will beep when it sees Ctrl-C from keyboard.)
  55.      */
  56.     if (kbhit())
  57.         getkey();
  58. #endif
  59.     if (reading)
  60.         intread();
  61. }
  62.  
  63. #ifdef SIGTSTP
  64. /*
  65.  * "Stop" (^Z) signal handler.
  66.  */
  67.     /* ARGSUSED*/
  68.     static RETSIGTYPE
  69. stop(type)
  70.     int type;
  71. {
  72.     LSIGNAL(SIGTSTP, stop);
  73.     sigs |= S_STOP;
  74.     if (reading)
  75.         intread();
  76. }
  77. #endif
  78.  
  79. #ifdef SIGWINCH
  80. /*
  81.  * "Window" change handler
  82.  */
  83.     /* ARGSUSED*/
  84.     public RETSIGTYPE
  85. winch(type)
  86.     int type;
  87. {
  88.     LSIGNAL(SIGWINCH, winch);
  89.     sigs |= S_WINCH;
  90.     if (reading)
  91.         intread();
  92. }
  93. #else
  94. #ifdef SIGWIND
  95. /*
  96.  * "Window" change handler
  97.  */
  98.     /* ARGSUSED*/
  99.     public RETSIGTYPE
  100. winch(type)
  101.     int type;
  102. {
  103.     LSIGNAL(SIGWIND, winch);
  104.     sigs |= S_WINCH;
  105.     if (reading)
  106.         intread();
  107. }
  108. #endif
  109. #endif
  110.  
  111. #if MSDOS_COMPILER==WIN32C
  112. /*
  113.  * Handle CTRL-C and CTRL-BREAK keys.
  114.  */
  115. #include "windows.h"
  116.  
  117.     static BOOL WINAPI 
  118. wbreak_handler(dwCtrlType)
  119.     DWORD dwCtrlType;
  120. {
  121.     switch (dwCtrlType)
  122.     {
  123.     case CTRL_C_EVENT:
  124.     case CTRL_BREAK_EVENT:
  125.         sigs |= S_INTERRUPT;
  126.         return (TRUE);
  127.     default:
  128.         break;
  129.     }
  130.     return (FALSE);
  131. }
  132. #endif
  133.  
  134. /*
  135.  * Set up the signal handlers.
  136.  */
  137.     public void
  138. init_signals(on)
  139.     int on;
  140. {
  141.     if (on)
  142.     {
  143.         /*
  144.          * Set signal handlers.
  145.          */
  146.         (void) LSIGNAL(SIGINT, u_interrupt);
  147. #if MSDOS_COMPILER==WIN32C
  148.         SetConsoleCtrlHandler(wbreak_handler, TRUE);
  149. #endif
  150. #ifdef SIGTSTP
  151.         (void) LSIGNAL(SIGTSTP, stop);
  152. #endif
  153. #ifdef SIGWINCH
  154.         (void) LSIGNAL(SIGWINCH, winch);
  155. #else
  156. #ifdef SIGWIND
  157.         (void) LSIGNAL(SIGWIND, winch);
  158. #endif
  159. #ifdef SIGQUIT
  160.         (void) LSIGNAL(SIGQUIT, SIG_IGN);
  161. #endif
  162. #endif
  163.     } else
  164.     {
  165.         /*
  166.          * Restore signals to defaults.
  167.          */
  168.         (void) LSIGNAL(SIGINT, SIG_DFL);
  169. #if MSDOS_COMPILER==WIN32C
  170.         SetConsoleCtrlHandler(wbreak_handler, FALSE);
  171. #endif
  172. #ifdef SIGTSTP
  173.         (void) LSIGNAL(SIGTSTP, SIG_DFL);
  174. #endif
  175. #ifdef SIGWINCH
  176.         (void) LSIGNAL(SIGWINCH, SIG_IGN);
  177. #endif
  178. #ifdef SIGWIND
  179.         (void) LSIGNAL(SIGWIND, SIG_IGN);
  180. #endif
  181. #ifdef SIGQUIT
  182.         (void) LSIGNAL(SIGQUIT, SIG_DFL);
  183. #endif
  184.     }
  185. }
  186.  
  187. /*
  188.  * Process any signals we have received.
  189.  * A received signal cause a bit to be set in "sigs".
  190.  */
  191.     public void
  192. psignals()
  193. {
  194.     register int tsignals;
  195.  
  196.     if ((tsignals = sigs) == 0)
  197.         return;
  198.     sigs = 0;
  199.  
  200. #ifdef SIGTSTP
  201.     if (tsignals & S_STOP)
  202.     {
  203.         /*
  204.          * Clean up the terminal.
  205.          */
  206. #ifdef SIGTTOU
  207.         LSIGNAL(SIGTTOU, SIG_IGN);
  208. #endif
  209.         clear_bot();
  210.         deinit();
  211.         flush();
  212.         raw_mode(0);
  213. #ifdef SIGTTOU
  214.         LSIGNAL(SIGTTOU, SIG_DFL);
  215. #endif
  216.         LSIGNAL(SIGTSTP, SIG_DFL);
  217.         kill(getpid(), SIGTSTP);
  218.         /*
  219.          * ... Bye bye. ...
  220.          * Hopefully we'll be back later and resume here...
  221.          * Reset the terminal and arrange to repaint the
  222.          * screen when we get back to the main command loop.
  223.          */
  224.         LSIGNAL(SIGTSTP, stop);
  225.         raw_mode(1);
  226.         init();
  227.         screen_trashed = 1;
  228.         tsignals |= S_WINCH;
  229.     }
  230. #endif
  231. #ifdef S_WINCH
  232.     if (tsignals & S_WINCH)
  233.     {
  234.         int old_width, old_height;
  235.         /*
  236.          * Re-execute scrsize() to read the new window size.
  237.          */
  238.         old_width = sc_width;
  239.         old_height = sc_height;
  240.         get_term();
  241.         if (sc_width != old_width || sc_height != old_height)
  242.         {
  243.             wscroll = (sc_height + 1) / 2;
  244.             screen_trashed = 1;
  245.         }
  246.     }
  247. #endif
  248.     if (tsignals & S_INTERRUPT)
  249.     {
  250.         bell();
  251.         /*
  252.          * {{ You may wish to replace the bell() with 
  253.          *    error("Interrupt", NULL_PARG); }}
  254.          */
  255.  
  256.         /*
  257.          * If we were interrupted while in the "calculating 
  258.          * line numbers" loop, turn off line numbers.
  259.          */
  260.         if (lnloop)
  261.         {
  262.             lnloop = 0;
  263.             if (linenums == 2)
  264.                 screen_trashed = 1;
  265.             linenums = 0;
  266.             error("Line numbers turned off", NULL_PARG);
  267.         }
  268.  
  269.     }
  270. }
  271.