home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / less_332.lzh / less_332 / signal.c < prev    next >
Text File  |  1998-03-03  |  6KB  |  281 lines

  1. /*
  2.  * Copyright (c) 1984,1985,1989,1994,1995,1996  Mark Nudelman
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice in the documentation and/or other materials provided with 
  12.  *    the distribution.
  13.  *
  14.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
  15.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
  17.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
  18.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
  19.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
  20.  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
  21.  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
  22.  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
  23.  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 
  24.  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25.  */
  26.  
  27.  
  28. /*
  29.  * Routines dealing with signals.
  30.  *
  31.  * A signal usually merely causes a bit to be set in the "signals" word.
  32.  * At some convenient time, the mainline code checks to see if any
  33.  * signals need processing by calling psignal().
  34.  * If we happen to be reading from a file [in iread()] at the time
  35.  * the signal is received, we call intread to interrupt the iread.
  36.  */
  37.  
  38. #include "less.h"
  39. #include <signal.h>
  40.  
  41. /*
  42.  * "sigs" contains bits indicating signals which need to be processed.
  43.  */
  44. public int sigs;
  45.  
  46. extern int sc_width, sc_height;
  47. extern int screen_trashed;
  48. extern int lnloop;
  49. extern int linenums;
  50. extern int wscroll;
  51. extern int reading;
  52.  
  53. /*
  54.  * Interrupt signal handler.
  55.  */
  56.     /* ARGSUSED*/
  57.     static RETSIGTYPE
  58. u_interrupt(type)
  59.     int type;
  60. {
  61. #if OS2
  62.     LSIGNAL(SIGINT, SIG_ACK);
  63. #endif
  64.     LSIGNAL(SIGINT, u_interrupt);
  65.     sigs |= S_INTERRUPT;
  66. #if MSDOS_COMPILER==DJGPPC
  67.     /*
  68.      * If a keyboard has been hit, it must be Ctrl-C
  69.      * (as opposed to Ctrl-Break), so consume it.
  70.      * (Otherwise, Less will beep when it sees Ctrl-C from keyboard.)
  71.      */
  72.     if (kbhit())
  73.         getkey();
  74. #endif
  75.     if (reading)
  76.         intread();
  77. }
  78.  
  79. #ifdef SIGTSTP
  80. /*
  81.  * "Stop" (^Z) signal handler.
  82.  */
  83.     /* ARGSUSED*/
  84.     static RETSIGTYPE
  85. stop(type)
  86.     int type;
  87. {
  88.     LSIGNAL(SIGTSTP, stop);
  89.     sigs |= S_STOP;
  90.     if (reading)
  91.         intread();
  92. }
  93. #endif
  94.  
  95. #ifdef SIGWINCH
  96. /*
  97.  * "Window" change handler
  98.  */
  99.     /* ARGSUSED*/
  100.     public RETSIGTYPE
  101. winch(type)
  102.     int type;
  103. {
  104.     LSIGNAL(SIGWINCH, winch);
  105.     sigs |= S_WINCH;
  106.     if (reading)
  107.         intread();
  108. }
  109. #else
  110. #ifdef SIGWIND
  111. /*
  112.  * "Window" change handler
  113.  */
  114.     /* ARGSUSED*/
  115.     public RETSIGTYPE
  116. winch(type)
  117.     int type;
  118. {
  119.     LSIGNAL(SIGWIND, winch);
  120.     sigs |= S_WINCH;
  121.     if (reading)
  122.         intread();
  123. }
  124. #endif
  125. #endif
  126.  
  127. #if MSDOS_COMPILER==WIN32C
  128. /*
  129.  * Handle CTRL-C and CTRL-BREAK keys.
  130.  */
  131. #include "windows.h"
  132.  
  133.     static BOOL WINAPI 
  134. wbreak_handler(dwCtrlType)
  135.     DWORD dwCtrlType;
  136. {
  137.     switch (dwCtrlType)
  138.     {
  139.     case CTRL_C_EVENT:
  140.     case CTRL_BREAK_EVENT:
  141.         sigs |= S_INTERRUPT;
  142.         return (TRUE);
  143.     default:
  144.         break;
  145.     }
  146.     return (FALSE);
  147. }
  148. #endif
  149.  
  150. /*
  151.  * Set up the signal handlers.
  152.  */
  153.     public void
  154. init_signals(on)
  155.     int on;
  156. {
  157.     if (on)
  158.     {
  159.         /*
  160.          * Set signal handlers.
  161.          */
  162.         (void) LSIGNAL(SIGINT, u_interrupt);
  163. #if MSDOS_COMPILER==WIN32C
  164.         SetConsoleCtrlHandler(wbreak_handler, TRUE);
  165. #endif
  166. #ifdef SIGTSTP
  167.         (void) LSIGNAL(SIGTSTP, stop);
  168. #endif
  169. #ifdef SIGWINCH
  170.         (void) LSIGNAL(SIGWINCH, winch);
  171. #else
  172. #ifdef SIGWIND
  173.         (void) LSIGNAL(SIGWIND, winch);
  174. #endif
  175. #endif
  176.     } else
  177.     {
  178.         /*
  179.          * Restore signals to defaults.
  180.          */
  181.         (void) LSIGNAL(SIGINT, SIG_DFL);
  182. #if MSDOS_COMPILER==WIN32C
  183.         SetConsoleCtrlHandler(wbreak_handler, FALSE);
  184. #endif
  185. #ifdef SIGTSTP
  186.         (void) LSIGNAL(SIGTSTP, SIG_DFL);
  187. #endif
  188. #ifdef SIGWINCH
  189.         (void) LSIGNAL(SIGWINCH, SIG_IGN);
  190. #endif
  191. #ifdef SIGWIND
  192.         (void) LSIGNAL(SIGWIND, SIG_IGN);
  193. #endif
  194.     }
  195. }
  196.  
  197. /*
  198.  * Process any signals we have received.
  199.  * A received signal cause a bit to be set in "sigs".
  200.  */
  201.     public void
  202. psignals()
  203. {
  204.     register int tsignals;
  205.  
  206.     if ((tsignals = sigs) == 0)
  207.         return;
  208.     sigs = 0;
  209.  
  210. #ifdef SIGTSTP
  211.     if (tsignals & S_STOP)
  212.     {
  213.         /*
  214.          * Clean up the terminal.
  215.          */
  216. #ifdef SIGTTOU
  217.         LSIGNAL(SIGTTOU, SIG_IGN);
  218. #endif
  219.         clear_bot();
  220.         deinit();
  221.         flush();
  222.         raw_mode(0);
  223. #ifdef SIGTTOU
  224.         LSIGNAL(SIGTTOU, SIG_DFL);
  225. #endif
  226.         LSIGNAL(SIGTSTP, SIG_DFL);
  227.         kill(getpid(), SIGTSTP);
  228.         /*
  229.          * ... Bye bye. ...
  230.          * Hopefully we'll be back later and resume here...
  231.          * Reset the terminal and arrange to repaint the
  232.          * screen when we get back to the main command loop.
  233.          */
  234.         LSIGNAL(SIGTSTP, stop);
  235.         raw_mode(1);
  236.         init();
  237.         screen_trashed = 1;
  238.         tsignals |= S_WINCH;
  239.     }
  240. #endif
  241. #ifdef S_WINCH
  242.     if (tsignals & S_WINCH)
  243.     {
  244.         int old_width, old_height;
  245.         /*
  246.          * Re-execute scrsize() to read the new window size.
  247.          */
  248.         old_width = sc_width;
  249.         old_height = sc_height;
  250.         get_term();
  251.         if (sc_width != old_width || sc_height != old_height)
  252.         {
  253.             wscroll = (sc_height + 1) / 2;
  254.             screen_trashed = 1;
  255.         }
  256.     }
  257. #endif
  258.     if (tsignals & S_INTERRUPT)
  259.     {
  260.         bell();
  261.         /*
  262.          * {{ You may wish to replace the bell() with 
  263.          *    error("Interrupt", NULL_PARG); }}
  264.          */
  265.  
  266.         /*
  267.          * If we were interrupted while in the "calculating 
  268.          * line numbers" loop, turn off line numbers.
  269.          */
  270.         if (lnloop)
  271.         {
  272.             lnloop = 0;
  273.             if (linenums == 2)
  274.                 screen_trashed = 1;
  275.             linenums = 0;
  276.             error("Line numbers turned off", NULL_PARG);
  277.         }
  278.  
  279.     }
  280. }
  281.