1: /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.00/RCS/tc.sig.c,v 3.0 1991/07/04 23:34:26 christos Exp $ */
   2: /*
   3:  * sh.sig.c: Signal routine emulations
   4:  */
   5: /*-
   6:  * Copyright (c) 1980, 1991 The Regents of the University of California.
   7:  * All rights reserved.
   8:  *
   9:  * Redistribution and use in source and binary forms, with or without
  10:  * modification, are permitted provided that the following conditions
  11:  * are met:
  12:  * 1. Redistributions of source code must retain the above copyright
  13:  *    notice, this list of conditions and the following disclaimer.
  14:  * 2. Redistributions in binary form must reproduce the above copyright
  15:  *    notice, this list of conditions and the following disclaimer in the
  16:  *    documentation and/or other materials provided with the distribution.
  17:  * 3. All advertising materials mentioning features or use of this software
  18:  *    must display the following acknowledgement:
  19:  *	This product includes software developed by the University of
  20:  *	California, Berkeley and its contributors.
  21:  * 4. Neither the name of the University nor the names of its contributors
  22:  *    may be used to endorse or promote products derived from this software
  23:  *    without specific prior written permission.
  24:  *
  25:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35:  * SUCH DAMAGE.
  36:  */
  37: #include "config.h"
  38: #if !defined(lint) && !defined(pdp11)
  39: static char *rcsid()
  40:     { return "$Id: tc.sig.c,v 3.0 1991/07/04 23:34:26 christos Exp $"; }
  41: #endif
  42: 
  43: #include "sh.h"
  44: /*
  45:  * a little complicated #include <sys/wait.h>! :-(
  46:  */
  47: #if SVID > 0
  48: # ifdef hpux
  49: #  ifndef __hpux
  50: #   include "tc.wait.h" /* 6.5 broke <sys/wait.h> */
  51: #  else
  52: #   ifndef POSIX
  53: #    define _BSD
  54: #   endif
  55: #   ifndef _CLASSIC_POSIX_TYPES
  56: #    define _CLASSIC_POSIX_TYPES
  57: #   endif
  58: #   include <sys/wait.h> /* 7.0 fixed it again */
  59: #  endif /* __hpux */
  60: # else /* hpux */
  61: #  if defined(OREO) || defined(IRIS4D) || defined(POSIX)
  62: #   include <sys/wait.h>
  63: #  else /* OREO || IRIS4D || POSIX */
  64: #   include "tc.wait.h"
  65: #  endif /* OREO || IRIS4D || POSIX */
  66: # endif	/* hpux */
  67: #else /* SVID == 0 */
  68: # include <sys/wait.h>
  69: #endif /* SVID == 0 */
  70: 
  71: #ifndef BSDSIGS
  72: /* libc.a contains these functions in SVID >= 3. */
  73: #if SVID < 3 || defined(UNIXPC)
  74: sigret_t
  75: (*sigset(a, b)) ()
  76:     int     a;
  77:     int     (*b) ();
  78: {
  79:     return (signal(a, b));
  80: }
  81: 
  82: /* release signal
  83:  *	release all queued signals and
  84:  *	set the default signal handler
  85:  */
  86: void
  87: sigrelse(what)
  88:     int     what;
  89: {
  90:     if (what == SIGCHLD)
  91:     sig_ch_rel();
  92: }
  93: 
  94: /* hold signal
  95:  * only works with child and interrupt
  96:  */
  97: void
  98: sighold(what)
  99:     int     what;
 100: {
 101:     int     sig_ch_queue();
 102: 
 103:     if (what == SIGCHLD)
 104:     (void) signal(SIGCHLD, sig_ch_queue);
 105: }
 106: 
 107: /* ignore signal
 108:  */
 109: void
 110: sigignore(a)
 111:     int     a;
 112: {
 113:     (void) signal(a, SIG_IGN);
 114: }
 115: 
 116: #endif				/* SVID < 3 || (UNIXPC) */
 117: 
 118: /* this stack is used to queue signals
 119:  * we can handle up to MAX_CHLD outstanding children now;
 120:  */
 121: #define MAX_CHLD 50
 122: static struct mysigstack {
 123:     int     s_w;        /* wait report			 */
 124:     int     s_errno;        /* errno returned;		 */
 125:     int     s_pid;      /* pid returned			 */
 126: }       stk[MAX_CHLD];
 127: static int stk_ptr = -1;
 128: 
 129: 
 130: /* return either awaiting processes or do a wait now
 131:  */
 132: int
 133: ourwait(w)
 134:     int    *w;
 135: {
 136:     int     pid;
 137: 
 138: #ifdef JOBDEBUG
 139:     xprintf("our wait %d\n", stk_ptr);
 140:     flush();
 141: #endif				/* JOBDEBUG */
 142: 
 143:     if (stk_ptr == -1) {
 144:     /* stack empty return signal from stack */
 145:     pid = wait(w);
 146: #ifdef JOBDEBUG
 147:     xprintf("signal(SIGCHLD, pchild);\n");
 148: #endif				/* JOBDEBUG */
 149:     (void) signal(SIGCHLD, pchild);
 150:     return (pid);
 151:     }
 152:     else {
 153:     /* return signal from stack */
 154:     errno = stk[stk_ptr].s_errno;
 155:     *w = stk[stk_ptr].s_w;
 156:     stk_ptr--;
 157:     return (stk[stk_ptr + 1].s_pid);
 158:     }
 159: }               /* end ourwait */
 160: 
 161: /* queue child signals
 162:  *
 163:  */
 164: static void
 165: sig_ch_queue()
 166: {
 167: #ifdef JOBDEBUG
 168:     xprintf("queue SIGCHLD\n");
 169:     flush();
 170: #endif				/* JOBDEBUG */
 171:     stk_ptr++;
 172:     stk[stk_ptr].s_pid = wait(&stk[stk_ptr].s_w);
 173:     stk[stk_ptr].s_errno = errno;
 174:     (void) signal(SIGCHLD, sig_ch_queue);
 175: }
 176: 
 177: 
 178: 
 179: 
 180: /* process all awaiting child signals
 181:  */
 182: static void
 183: sig_ch_rel()
 184: {
 185:     while (stk_ptr > -1)
 186:     pchild(SIGCHLD);
 187: #ifdef JOBDEBUG
 188:     xprintf("signal(SIGCHLD, pchild);\n");
 189: #endif				/* JOBDEBUG */
 190:     (void) signal(SIGCHLD, pchild);
 191: }
 192: 
 193: /* libc.a contains sigpause.o in SVID >= 3. */
 194: #if SVID < 3 || defined(UNIXPC)
 195: 
 196: /* atomically release one signal
 197:  */
 198: void
 199: sigpause(what)
 200:     int     what;
 201: {
 202: #ifdef notdef
 203:     if (what == SIGCHLD) {
 204:     if (stk_ptr > -1) {
 205:         pchild(SIGCHLD);
 206:     }
 207:     else {
 208:         (void) sleep(1);
 209:     }
 210:     }
 211: #endif
 212:     /* From: Jim Mattson <mattson%cs@ucsd.edu> */
 213:     if (what == SIGCHLD)
 214:     pchild(SIGCHLD);
 215: 
 216: }
 217: 
 218: #endif				/* SVID < 3 || (UNIXPC) */
 219: 
 220: #ifdef SXA
 221: /*
 222:  * SX/A is SVID3 but does not have sys5-sigpause().
 223:  * I've heard that sigpause() is not defined in SVID3.
 224:  */
 225: /* This is not need if you make tcsh by BSD option's cc. */
 226: void
 227: sigpause(what)
 228: {
 229:     if (what == SIGCHLD) {
 230:     b_sigpause(b_sigblock((sigmask_t) 0) & ~sigmask(SIGBSDCHLD));
 231:     }
 232:     else if (what == 0) {
 233:     pause();
 234:     }
 235:     else {
 236:     xprintf("sigpause(%d)\n", what);
 237:     pause();
 238:     }
 239: }
 240: 
 241: #endif				/* SXA */
 242: #endif				/* BSDSIGS */
 243: 
 244: #ifdef NEEDsignal
 245: /* turn into bsd signals */
 246: sigret_t(*
 247:      xsignal(s, a)) ()
 248:     int     s;
 249: 
 250: sigret_t(*a) ();
 251: {
 252:     sigvec_t osv, sv;
 253: 
 254:     (void) mysigvec(s, NULL, &osv);
 255:     sv = osv;
 256:     sv.sv_handler = a;
 257: #ifdef SIG_STK
 258:     sv.sv_onstack = SIG_STK;
 259: #endif
 260: #if defined(SV_BSDSIG) && defined(SV_ONSTACK)
 261:     sv.sv_flags = SV_BSDSIG | SV_ONSTACK;
 262: #endif
 263: 
 264:     if (mysigvec(s, &sv, NULL) < 0)
 265:     return (BADSIG);
 266:     return (osv.sv_handler);
 267: }
 268: 
 269: #endif /* NEEDsignal */
 270: 
 271: #ifdef _SEQUENT_
 272: /*
 273:  * Support for signals.
 274:  */
 275: 
 276: extern int errno;
 277: 
 278: /* Set and test a bit.  Bits numbered 1 to 32 */
 279: 
 280: #define SETBIT(x, y)    x |= sigmask(y)
 281: #define ISSET(x, y) ((x & sigmask(y)) != 0)
 282: 
 283: #ifdef DEBUG
 284: # define SHOW_SIGNALS   1   /* to assist in debugging signals */
 285: #endif
 286: 
 287: #ifdef SHOW_SIGNALS
 288: char   *show_sig_mask();
 289: #endif
 290: 
 291: int     debug_signals = 0;
 292: 
 293: /*
 294:  * igsetmask(mask)
 295:  *
 296:  * Set a new signal mask.  Return old mask.
 297:  */
 298: sigmask_t
 299: sigsetmask(mask)
 300:     sigmask_t     mask;
 301: {
 302:     sigset_t set, oset;
 303:     int     m;
 304:     register int i;
 305: 
 306:     sigemptyset(&set);
 307:     sigemptyset(&oset);
 308: 
 309:     for (i = 1; i <= MAXSIG; i++)
 310:     if (ISSET(mask, i))
 311:         sigaddset(&set, i);
 312: 
 313:     if (sigprocmask(SIG_SETMASK, &set, &oset))
 314:     xprintf("sigsetmask(0x%x) - sigprocmask failed, errno %d",
 315:         mask, errno);
 316: 
 317:     m = 0;
 318:     for (i = 1; i < MAXSIG; i++)
 319:     if (sigismember(&oset, i))
 320:         SETBIT(m, i);
 321: 
 322:     return (m);
 323: }
 324: 
 325: /*
 326:  * sigblock(mask)
 327:  *
 328:  * Add "mask" set of signals to the present signal mask.
 329:  * Return old mask.
 330:  */
 331: sigmask_t
 332: sigblock(mask)
 333:     sigmask_t     mask;
 334: {
 335:     sigset_t set, oset;
 336:     int     m;
 337:     register int i;
 338: 
 339:     set = 0;
 340:     oset = 0;
 341: 
 342:     /* Get present set of signals. */
 343:     if (sigprocmask(SIG_SETMASK, NULL, &set))
 344:     xprintf("sigblock(0x%x) - sigprocmask failed, errno %d",
 345:         mask, errno);
 346: 
 347:     /* Add in signals from mask. */
 348:     for (i = 1; i <= MAXSIG; i++)
 349:     if (ISSET(mask, i))
 350:         sigaddset(&set, i);
 351: 
 352:     sigprocmask(SIG_SETMASK, &set, &oset);
 353: 
 354:     /* Return old mask to user. */
 355:     m = 0;
 356:     for (i = 1; i < MAXSIG; i++)
 357:     if (sigismember(&oset, i))
 358:         SETBIT(m, i);
 359: 
 360:     return (m);
 361: }
 362: 
 363: 
 364: /*
 365:  * b_sigpause(mask)
 366:  *
 367:  * Set new signal mask and wait for signal;
 368:  * Old mask is restored on signal.
 369:  */
 370: void
 371: b_sigpause(mask)
 372:     sigmask_t     mask;
 373: {
 374:     sigset_t set;
 375:     register int i;
 376: 
 377:     sigemptyset(&set);
 378: 
 379:     for (i = 1; i <= MAXSIG; i++)
 380:     if (ISSET(mask, i))
 381:         sigaddset(&set, i);
 382:     sigsuspend(&set);
 383: }
 384: 
 385: #endif				/* _SEQUENT_ */
 386: 
 387: 
 388: #ifdef SIGSYNCH
 389: static long Synch_Cnt = 0;
 390: 
 391: sigret_t
 392: synch_handler(sno)
 393: int sno;
 394: {
 395:     if (sno != SIGSYNCH)
 396:     abort();
 397:     Synch_Cnt++;
 398: }
 399: 
 400: #endif				/* SIGSYNCH */

Defined functions

b_sigpause defined in line 370; used 2 times
ourwait defined in line 132; used 2 times
rcsid defined in line 39; never used
sig_ch_queue defined in line 164; used 3 times
sig_ch_rel defined in line 182; used 1 times
  • in line 91
sighold defined in line 97; used 4 times
sigignore defined in line 109; never used
sigpause defined in line 226; used 3 times
sigrelse defined in line 86; used 2 times
synch_handler defined in line 391; used 1 times

Defined variables

Synch_Cnt defined in line 389; used 1 times
a defined in line 76; used 8 times
debug_signals defined in line 291; never used
s defined in line 248; used 3 times
stk defined in line 126; used 6 times
stk_ptr defined in line 127; used 12 times

Defined struct's

mysigstack defined in line 122; never used

Defined macros

ISSET defined in line 281; used 3 times
MAX_CHLD defined in line 121; used 1 times
SETBIT defined in line 280; used 2 times
SHOW_SIGNALS defined in line 284; used 1 times
_BSD defined in line 53; never used
_CLASSIC_POSIX_TYPES defined in line 56; used 1 times
  • in line 55
Last modified: 1991-08-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 44
Valid CSS Valid XHTML 1.0 Strict