home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Kernel / SigHandling / setHandler.c < prev   
Encoding:
C/C++ Source or Header  |  1990-08-17  |  3.0 KB  |  108 lines

  1. #ifdef BSD
  2. #include <stdio.h>
  3. #include <sys/types.h>
  4. #include <signal.h>
  5.  
  6. extern int errno;
  7.  
  8. #undef integer        /* Silly stdtypes */
  9. #include "Kernel/h/system.h"
  10. #include "Kernel/h/stdTypes.h"
  11. #include "Kernel/h/kEvents.h"
  12. #include "Kernel/h/kmdTypes.h"
  13.  
  14. extern void EmeraldSigUpCall();
  15.  
  16. /*
  17.  * SetHandler(signal, handler)
  18.  *
  19.  * Signal is a Unix signal.  Handler is a pointer to a function which
  20.  * handles that signal.
  21.  *
  22.  * Called by other modules in the kernel to specify that a particular
  23.  * routine is to be called when a signal comes in.  Analogous to the
  24.  * Unix system call sigset().  The main difference is that critical
  25.  * sections can be protected by calls to HoldSigs and ReleaseSigs, in
  26.  * which case the call to the handler is deferred until the call to
  27.  * ReleaseSigs.
  28.  * Revised to access an array of pointers to the active signal table
  29.  * entries, and to conform to new signal hold/release protocol. 
  30.  * [Eric Jul, Aug. 1983.]
  31.  *
  32.  * Modified June 1986 to use alternative signal stack and to hold
  33.  * other signals while in a signal handler (as to keep overhead down
  34.  * and avoid signal stack overflow).
  35.  */
  36.  
  37.  
  38. #define THESIGMASK \
  39.                 1<<SIGPIPE | \
  40.                 1<<SIGALRM | \
  41.                 1<<SIGURG  | \
  42.                 1<<SIGCHLD | \
  43.                 1<<SIGIO   | \
  44.                 1<<SIGXCPU | \
  45.                 1<<SIGXFSZ | \
  46.                 1<<SIGVTALRM | \
  47.                 1<<28      | \
  48.                 1<<29      | \
  49.                 1<<30
  50.  
  51. void SetHandler(sig, handler)
  52. int sig;
  53. void (* handler)();
  54. /* Set a signal handler in a way so that HoldSigs and ReleaseSigs
  55.    may be used to block the signal */
  56. {
  57.         /*
  58.      * It is assumed that the alternate signal stack has already
  59.          * been defined using sigstack
  60.      */
  61.         struct sigvec vec;
  62.  
  63.     DebugMsg(4, "Setting #%d signal %d handler = 0x%08x\n", ActCount, sig,
  64.         handler);
  65.  
  66.     SigTable[sig].Handler = handler;
  67.         ActSig[ActCount++] = sig;
  68.     vec.sv_handler = RealSigHandler;
  69.     vec.sv_mask = THESIGMASK;
  70.     vec.sv_onstack = 1; /* use the alternate stack */
  71.     if (sigvec(sig, &vec, 0) == -1) {
  72.             perror("sigvec");
  73.             abort();
  74.         };
  75. }
  76.  
  77. /*
  78.  * RealSigHandler(sig)
  79.  *
  80.  * This is the routine that runs at interrupt time.
  81.  *
  82.  * Little known fact:  Signal handlers are given the signal number as
  83.  * first argument.  This is undocumented as far as I know.  We probably
  84.  * shouldn't rely on undocumented "features".
  85.  * Note for later versions: It is a documented feature of Unix 4.2bsd.
  86.  */
  87.  
  88. RealSigHandler(sig)
  89. int sig;
  90. {
  91.     register int savedErrno;  /* Signal handler must not destroy errno */
  92.         savedErrno = errno;
  93.     DebugMsg(4, "Signal %d has arrived\n", sig);
  94.     /* The following call tells the Emerald kernel about the signal */
  95.     EmeraldSigUpCall(sig);
  96.         errno = savedErrno;
  97.     if (SigsHeld) {
  98.         SigTable[sig].Ntimes++;
  99.                 Pending = 1;
  100.                 DebugMsg(5, "  signal count now: %d\n", SigTable[sig].Ntimes);
  101.     }
  102.     else
  103.         (SigTable[sig].Handler)(sig);
  104.     errno = savedErrno;
  105. }
  106.  
  107. #endif BSD
  108.