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:  * An exception is made if we are reading from the keyboard when the
   8:  * signal is received.  Some operating systems will simply call the
   9:  * signal handler and NOT return from the read (with EINTR).
  10:  * To handle this case, we service the interrupt directly from
  11:  * the handler if we are reading from the keyboard.
  12:  */
  13: 
  14: #include "less.h"
  15: #include <signal.h>
  16: #include <setjmp.h>
  17: 
  18: /*
  19:  * The type of signal handler functions.
  20:  * Usually int, although it should be void.
  21:  */
  22: typedef int     HANDLER;
  23: 
  24: /*
  25:  * "sigs" contains bits indicating signals which need to be processed.
  26:  */
  27: public int sigs;
  28: #define S_INTERRUPT 01
  29: #ifdef SIGTSTP
  30: #define S_STOP      02
  31: #endif
  32: #ifdef  NRTC
  33: #define S_QUIT      04
  34: #endif	NRTC
  35: 
  36: extern int reading;
  37: extern char *first_cmd;
  38: extern jmp_buf main_loop;
  39: 
  40: /*
  41:  * Interrupt signal handler.
  42:  */
  43:     static HANDLER
  44: interrupt()
  45: {
  46:     SIGNAL(SIGINT, interrupt);
  47:     sigs |= S_INTERRUPT;
  48:     if (reading)
  49:         psignals();
  50: }
  51: 
  52: #ifdef  NRTC
  53: /*
  54:  * Interrupt signal handler.
  55:  */
  56:     static HANDLER
  57: quitnow ()
  58: {
  59:     SIGNAL(SIGQUIT, quitnow);
  60:     sigs |= S_QUIT;
  61:     if (reading)
  62:         psignals();
  63: }
  64: #endif	NRTC
  65: 
  66: #ifdef SIGTSTP
  67: /*
  68:  * "Stop" (^Z) signal handler.
  69:  */
  70:     static HANDLER
  71: stop()
  72: {
  73:     SIGNAL(SIGTSTP, stop);
  74:     sigs |= S_STOP;
  75:     if (reading)
  76:         psignals();
  77: }
  78: #endif
  79: 
  80: /*
  81:  * Set up the signal handlers.
  82:  */
  83:     public void
  84: init_signals()
  85: {
  86:     (void) SIGNAL(SIGINT, interrupt);
  87: #ifdef  NRTC
  88:     (void) SIGNAL (SIGQUIT, quitnow);
  89: #endif	NRTC
  90: #ifdef SIGTSTP
  91:     (void) SIGNAL(SIGTSTP, stop);
  92: #endif
  93: }
  94: 
  95: /*
  96:  * Process any signals we have recieved.
  97:  * A received signal cause a bit to be set in "sigs".
  98:  */
  99:     public void
 100: psignals()
 101: {
 102:     register int tsignals;
 103: 
 104:     tsignals = sigs;
 105:     sigs = 0;
 106:     if (tsignals == 0)
 107:         return;
 108: 
 109:     dropout();      /* Discard any buffered output */
 110: 
 111: #ifdef SIGTSTP
 112:     if (tsignals & S_STOP)
 113:     {
 114:         /*
 115: 		 * Clean up the terminal.
 116: 		 */
 117: #ifdef SIGTTOU
 118:         SIGNAL(SIGTTOU, SIG_IGN);
 119: #endif
 120:         lower_left();
 121:         clear_eol();
 122:         flush();
 123:         raw_mode(0);
 124: #ifdef SIGTTOU
 125:         SIGNAL(SIGTTOU, SIG_DFL);
 126: #endif
 127:         SIGNAL(SIGTSTP, SIG_DFL);
 128: #if SIGSETMASK
 129:         /*
 130: 		 * This system will not allow us to send a
 131: 		 * stop signal (SIGTSTP) to ourself
 132: 		 * while we are in the signal handler, like maybe now.
 133: 		 * (This can be the case if we are reading; see comment above.)
 134: 		 * So we ask the silly system for permission to do so.
 135: 		 */
 136:         sigsetmask(0);
 137: #endif
 138:         kill(getpid(), SIGTSTP);
 139:         /*
 140: 		 * ... Bye bye. ...
 141: 		 * Hopefully we'll be back later and resume here...
 142: 		 * Reset the terminal and arrange to repaint the
 143: 		 * screen when we get back to the main command loop.
 144: 		 */
 145:         SIGNAL(SIGTSTP, stop);
 146:         raw_mode(1);
 147:         first_cmd = "r";
 148:         longjmp(main_loop, 1);
 149:     }
 150: #endif
 151: #ifdef  NRTC
 152:     if (tsignals & S_QUIT)
 153:         quit ();
 154: #endif	NRTC
 155:     if (tsignals & S_INTERRUPT)
 156:     {
 157:         bell();
 158:         /*
 159: 		 * {{ You may wish to replace the bell() with
 160: 		 *    error("Interrupt"); }}
 161: 		 */
 162:     }
 163: 
 164:     longjmp(main_loop, 1);
 165: }
 166: 
 167: /*
 168:  * Pass the specified command to a shell to be executed.
 169:  * Like plain "system()", but handles resetting terminal modes, etc.
 170:  */
 171:     public void
 172: lsystem(cmd)
 173:     char *cmd;
 174: {
 175:     int inp;
 176: 
 177:     /*
 178: 	 * Print the command which is to be executed.
 179: 	 */
 180:     lower_left();
 181:     clear_eol();
 182:     puts("!");
 183:     puts(cmd);
 184:     puts("\n");
 185: 
 186:     /*
 187: 	 * De-initialize the terminal and take out of raw mode.
 188: 	 */
 189:     deinit();
 190:     flush();
 191:     raw_mode(0);
 192: 
 193:     /*
 194: 	 * Restore signals to their defaults.
 195: 	 */
 196:     SIGNAL(SIGINT, SIG_DFL);
 197: #ifdef SIGTSTP
 198:     SIGNAL(SIGTSTP, SIG_DFL);
 199: #endif
 200:     /*
 201: 	 * Pass the command to the system to be executed.
 202: 	 */
 203:     inp = dup(0);
 204:     close(0);
 205:     open("/dev/tty", 0);
 206: 
 207:     system(cmd);
 208: 
 209:     close(0);
 210:     dup(inp);
 211:     close(inp);
 212: 
 213:     /*
 214: 	 * Reset signals, raw mode, etc.
 215: 	 */
 216:     init_signals();
 217:     raw_mode(1);
 218:     init();
 219: }

Defined functions

interrupt defined in line 43; used 2 times
quitnow defined in line 56; used 2 times
stop defined in line 70; used 3 times

Defined variables

public defined in line 171; never used

Defined typedef's

HANDLER defined in line 22; used 3 times

Defined macros

S_INTERRUPT defined in line 28; used 2 times
S_QUIT defined in line 33; used 2 times
S_STOP defined in line 30; used 2 times
Last modified: 1986-04-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1689
Valid CSS Valid XHTML 1.0 Strict