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: 
  33: extern int reading;
  34: extern char *first_cmd;
  35: extern jmp_buf main_loop;
  36: 
  37: /*
  38:  * Interrupt signal handler.
  39:  */
  40:     static HANDLER
  41: interrupt()
  42: {
  43:     SIGNAL(SIGINT, interrupt);
  44:     sigs |= S_INTERRUPT;
  45:     if (reading)
  46:         psignals();
  47: }
  48: 
  49: #ifdef SIGTSTP
  50: /*
  51:  * "Stop" (^Z) signal handler.
  52:  */
  53:     static HANDLER
  54: stop()
  55: {
  56:     SIGNAL(SIGTSTP, stop);
  57:     sigs |= S_STOP;
  58:     if (reading)
  59:         psignals();
  60: }
  61: #endif
  62: 
  63: /*
  64:  * Set up the signal handlers.
  65:  */
  66:     public void
  67: init_signals()
  68: {
  69:     (void) SIGNAL(SIGINT, interrupt);
  70: #ifdef SIGTSTP
  71:     (void) SIGNAL(SIGTSTP, stop);
  72: #endif
  73: }
  74: 
  75: /*
  76:  * Process any signals we have recieved.
  77:  * A received signal cause a bit to be set in "sigs".
  78:  */
  79:     public void
  80: psignals()
  81: {
  82:     register int tsignals;
  83: 
  84:     tsignals = sigs;
  85:     sigs = 0;
  86:     if (tsignals == 0)
  87:         return;
  88: 
  89:     dropout();      /* Discard any buffered output */
  90: 
  91: #ifdef SIGTSTP
  92:     if (tsignals & S_STOP)
  93:     {
  94:         /*
  95: 		 * Clean up the terminal.
  96: 		 */
  97: #ifdef SIGTTOU
  98:         SIGNAL(SIGTTOU, SIG_IGN);
  99: #endif
 100:         lower_left();
 101:         clear_eol();
 102:         flush();
 103:         raw_mode(0);
 104: #ifdef SIGTTOU
 105:         SIGNAL(SIGTTOU, SIG_DFL);
 106: #endif
 107:         SIGNAL(SIGTSTP, SIG_DFL);
 108: #if SIGSETMASK
 109:         /*
 110: 		 * This system will not allow us to send a
 111: 		 * stop signal (SIGTSTP) to ourself
 112: 		 * while we are in the signal handler, like maybe now.
 113: 		 * (This can be the case if we are reading; see comment above.)
 114: 		 * So we ask the silly system for permission to do so.
 115: 		 */
 116:         sigsetmask(0);
 117: #endif
 118:         kill(getpid(), SIGTSTP);
 119:         /*
 120: 		 * ... Bye bye. ...
 121: 		 * Hopefully we'll be back later and resume here...
 122: 		 * Reset the terminal and arrange to repaint the
 123: 		 * screen when we get back to the main command loop.
 124: 		 */
 125:         SIGNAL(SIGTSTP, stop);
 126:         raw_mode(1);
 127:         first_cmd = "r";
 128:         longjmp(main_loop, 1);
 129:     }
 130: #endif
 131:     if (tsignals & S_INTERRUPT)
 132:     {
 133:         bell();
 134:         /*
 135: 		 * {{ You may wish to replace the bell() with
 136: 		 *    error("Interrupt"); }}
 137: 		 */
 138:     }
 139: 
 140:     longjmp(main_loop, 1);
 141: }
 142: 
 143: /*
 144:  * Pass the specified command to a shell to be executed.
 145:  * Like plain "system()", but handles resetting terminal modes, etc.
 146:  */
 147:     public void
 148: lsystem(cmd)
 149:     char *cmd;
 150: {
 151:     int inp;
 152: 
 153:     /*
 154: 	 * Print the command which is to be executed.
 155: 	 */
 156:     lower_left();
 157:     clear_eol();
 158:     puts("!");
 159:     puts(cmd);
 160:     puts("\n");
 161: 
 162:     /*
 163: 	 * De-initialize the terminal and take out of raw mode.
 164: 	 */
 165:     deinit();
 166:     flush();
 167:     raw_mode(0);
 168: 
 169:     /*
 170: 	 * Restore signals to their defaults.
 171: 	 */
 172:     SIGNAL(SIGINT, SIG_DFL);
 173: #ifdef SIGTSTP
 174:     SIGNAL(SIGTSTP, SIG_DFL);
 175: #endif
 176:     /*
 177: 	 * Pass the command to the system to be executed.
 178: 	 */
 179:     inp = dup(0);
 180:     close(0);
 181:     open("/dev/tty", 0);
 182: 
 183:     system(cmd);
 184: 
 185:     close(0);
 186:     dup(inp);
 187:     close(inp);
 188: 
 189:     /*
 190: 	 * Reset signals, raw mode, etc.
 191: 	 */
 192:     init_signals();
 193:     raw_mode(1);
 194:     init();
 195: }

Defined functions

init_signals defined in line 66; used 1 times
interrupt defined in line 40; used 2 times
lsystem defined in line 147; never used
psignals defined in line 79; used 2 times
stop defined in line 53; used 3 times

Defined variables

public defined in line 147; never used
sigs defined in line 27; used 4 times

Defined typedef's

HANDLER defined in line 22; used 2 times

Defined macros

S_INTERRUPT defined in line 28; 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: ?E00
Valid CSS Valid XHTML 1.0 Strict