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(0L);
 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: 	 * unless the command starts with a "-".
 156: 	 */
 157:     if (cmd[0] == '-')
 158:         cmd++;
 159:     else
 160:     {
 161:         lower_left();
 162:         clear_eol();
 163:         puts("!");
 164:         puts(cmd);
 165:         puts("\n");
 166:     }
 167: 
 168:     /*
 169: 	 * De-initialize the terminal and take out of raw mode.
 170: 	 */
 171:     deinit();
 172:     flush();
 173:     raw_mode(0);
 174: 
 175:     /*
 176: 	 * Restore signals to their defaults.
 177: 	 */
 178:     SIGNAL(SIGINT, SIG_DFL);
 179: #ifdef SIGTSTP
 180:     SIGNAL(SIGTSTP, SIG_DFL);
 181: #endif
 182:     /*
 183: 	 * Force standard input to be the terminal, "/dev/tty".
 184: 	 */
 185:     inp = dup(0);
 186:     close(0);
 187:     open("/dev/tty", 0);
 188: 
 189:     /*
 190: 	 * Pass the command to the system to be executed.
 191: 	 */
 192:     system(cmd);
 193: 
 194:     /*
 195: 	 * Restore standard input, reset signals, raw mode, etc.
 196: 	 */
 197:     close(0);
 198:     dup(inp);
 199:     close(inp);
 200: 
 201:     init_signals();
 202:     raw_mode(1);
 203:     init();
 204: }
 205: 
 206: /*
 207:  * Expand a filename, substituting any environment variables, etc.
 208:  * The implementation of this is necessarily very operating system
 209:  * dependent.  This implementation is unabashedly only for Unix systems.
 210:  */
 211: #if GLOB
 212: 
 213: #include <stdio.h>
 214: 
 215:     char *
 216: glob(filename)
 217:     char *filename;
 218: {
 219:     FILE *f;
 220:     char *p;
 221:     int ch;
 222:     static char filebuf[128];
 223:     static char ECHO[] = "echo ";
 224: 
 225:     strcpy(filebuf, ECHO);
 226:     strtcpy(filebuf+sizeof(ECHO)-1, filename, sizeof(filebuf)-sizeof(ECHO));
 227:     if ((f = popen(filebuf, "r")) == NULL)
 228:         return (filename);
 229:     for (p = filebuf;  p < &filebuf[sizeof(filebuf)-1];  p++)
 230:     {
 231:         if ((ch = getc(f)) == '\n' || ch == EOF)
 232:             break;
 233:         *p = ch;
 234:     }
 235:     *p = '\0';
 236:     pclose(f);
 237:     return (filebuf);
 238: }
 239: 
 240: #else
 241: 
 242:     char *
 243: glob(filename)
 244:     char *filename;
 245: {
 246:     return (filename);
 247: }
 248: 
 249: #endif

Defined functions

glob defined in line 242; used 1 times
init_signals defined in line 66; used 3 times
interrupt defined in line 40; used 2 times
psignals defined in line 79; used 4 times
stop defined in line 53; used 3 times

Defined variables

public defined in line 147; never used
sigs defined in line 27; used 8 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: 1997-09-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 489
Valid CSS Valid XHTML 1.0 Strict