home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib32.zoo / sigactio.c < prev    next >
C/C++ Source or Header  |  1993-06-17  |  4KB  |  235 lines

  1. /* sigaction() and sigset functions for MiNT; placed in the public domain */
  2.  
  3. #include <errno.h>
  4. #include <osbind.h>
  5. #include <mintbind.h>
  6. #include <signal.h>
  7.  
  8. /* vector of signal handlers (for TOS, or for MiNT with -mshort) */
  9. extern __Sigfunc _sig_handler[NSIG];
  10.  
  11. #ifdef __MSHORT__
  12. typedef void __CDECL (*__KerSigfunc) __PROTO((long));
  13. __EXTERN void __CDECL _trampoline __PROTO((long sig));
  14. #else
  15. typedef void __CDECL (*__KerSigfunc) __PROTO((int));
  16. #endif
  17.  
  18. int
  19. sigaction(sig, act, oact)
  20.     int sig;
  21.     const struct sigaction *act;
  22.     struct sigaction *oact;
  23. {
  24.     long r;
  25.     extern int __mint;
  26.     __Sigfunc oldfunc;
  27.  
  28.     if (__mint >= 95) {
  29.         struct ksigact {
  30.             __KerSigfunc    sa_handler;    /* pointer to signal handler */
  31.             long        sa_mask;    /* additional signals masked during delivery */
  32.             union {
  33.                 short    kernel;
  34.                 int        posix;
  35.             } sa_flags;        /* signal specific flags, kernel */
  36.         } temp;
  37.         
  38. #ifdef __MSHORT__
  39. /* NOTE: MiNT passes 32 bit numbers for signals, so we want our
  40.  * own signal dispatcher to switch these to 16 bit ints
  41.  */
  42.         if (sig < 0 || sig >= NSIG) {
  43.             errno = ERANGE;
  44.             return -1;
  45.         }
  46.         oldfunc = _sig_handler[sig];
  47.         if (act) {
  48.             temp = *(struct ksigact *)act;
  49.             _sig_handler[sig] = (__Sigfunc)temp.sa_handler;
  50.             if (_sig_handler[sig] != SIG_DFL && _sig_handler[sig] != SIG_IGN) {
  51.                 temp.sa_handler = _trampoline;
  52.             }
  53.             act = (struct sigaction *)&temp;
  54.         }
  55. #else
  56.         if (act) {
  57.             temp = *(struct ksigact *)act;    /* dept. of sleaze */
  58.             temp.sa_flags.kernel = temp.sa_flags.posix;
  59.             act = (struct sigaction *)&temp;
  60.         }
  61. #endif
  62.         r = Psigaction(sig, act, oact);
  63. #ifdef __MSHORT__
  64.         if (oact && oact->sa_handler == (__Sigfunc) _trampoline)
  65.             oact->sa_handler = oldfunc;
  66. #else
  67.         if (oact)
  68.             oact->sa_flags = ((struct ksigact *)oact)->sa_flags.kernel;
  69. #endif
  70.         if (r < 0) {
  71.             errno = (int) -r;
  72.             return -1;
  73.         }
  74.     }
  75.     else {
  76.         if (act)
  77.             oldfunc = signal(sig, act->sa_handler);
  78.         else {
  79.             long omask;
  80.  
  81.             omask = sigblock(sig);
  82.             oldfunc = signal(sig, SIG_DFL);
  83.             signal(sig, oldfunc);    /* need to put it back */
  84.             sigsetmask(omask);    /* may remask sig (this is what we want) */
  85.         }
  86.         if (oldfunc == SIG_ERR)
  87.             return -1;
  88.         if (oact) {
  89.             oact->sa_handler = oldfunc;
  90.             /* we could do something useful with sa_mask when __mint */
  91.             oact->sa_flags = 0;
  92.             oact->sa_mask = 0;
  93.         }
  94.     }
  95.     return 0;
  96. }
  97.  
  98. int
  99. sigaddset(set, signo)
  100.   sigset_t *set;
  101.   int signo;
  102. {
  103.   int idx;
  104.   int pos;
  105.  
  106.   if ((!set) || (signo >= NSIG)) {
  107.     errno = EINVAL;
  108.     return -1;
  109.   }
  110.   idx = _SIGSET_INDEX(signo);
  111.   pos = _SIGSET_BITPOS(signo);
  112.   set->_sigset_data[idx] |= sigmask(pos);
  113.   return 0;  
  114. }
  115.  
  116. int
  117. sigdelset(set, signo)
  118.   sigset_t *set;
  119.   int signo;
  120. {
  121.   int idx;
  122.   int pos;
  123.  
  124.   if ((!set) || (signo >= NSIG)) {
  125.     errno = EINVAL;
  126.     return -1;
  127.   }
  128.   idx = _SIGSET_INDEX(signo);
  129.   pos = _SIGSET_BITPOS(signo);
  130.   set->_sigset_data[idx] &= ~(sigmask(pos));
  131.   return 0;  
  132. }
  133.  
  134. int
  135. sigemptyset(set)
  136.   sigset_t *set;
  137. {
  138.   int idx;
  139.  
  140.   if (!set) {
  141.     errno = EINVAL;
  142.     return -1;
  143.   }
  144.   for (idx = _SIGSET_MAX_INDEX; idx >= 0; idx--) {
  145.     set->_sigset_data[idx] = 0UL;
  146.   }
  147.   return 0;  
  148. }
  149.  
  150. int
  151. sigfillset(set)
  152.   sigset_t *set;
  153. {
  154.   int idx;
  155.  
  156.   if (!set) {
  157.     errno = EINVAL;
  158.     return -1;
  159.   }
  160.   for (idx = _SIGSET_MAX_INDEX; idx >= 0; idx--) {
  161.     set->_sigset_data[idx] = ~0UL;
  162.   }
  163.   return 0;  
  164. }
  165.  
  166. int
  167. sigismember(set, signo)
  168.   sigset_t *set;
  169.   int signo;
  170. {
  171.   int idx;
  172.   int pos;
  173.  
  174.   if ((!set) || (signo >= NSIG)) {
  175.     errno = EINVAL;
  176.     return -1;
  177.   }
  178.   idx = _SIGSET_INDEX(signo);
  179.   pos = _SIGSET_BITPOS(signo);
  180.   return (set->_sigset_data[idx] & sigmask(pos)) ? 1 : 0;
  181. }
  182.  
  183. int
  184. sigpending(set)
  185.   sigset_t *set;
  186. {
  187.   if (!set) {
  188.     errno = EINVAL;
  189.     return -1;
  190.   }
  191.   (void) sigemptyset(set);
  192.   set->_sigset_data[0] = Psigpending();  
  193. }
  194.  
  195. int
  196. sigprocmask(how, set, oset)
  197.   int how;
  198.   const sigset_t *set;
  199.   sigset_t *oset;
  200. {
  201.   int rv = 0;
  202.   long omask = 0L;
  203.  
  204.   if (!set) {
  205.     errno = EINVAL;
  206.     return -1;
  207.   }
  208.   switch (how) {
  209.     case SIG_BLOCK:
  210.       omask = Psigblock(set->_sigset_data[0]);
  211.       break;
  212.     case SIG_UNBLOCK:
  213.       omask = Psigblock(0L);
  214.       (void) Psigsetmask(omask & ~(set->_sigset_data[0]));
  215.       break;
  216.     case SIG_SETMASK:
  217.       omask = Psigsetmask(set->_sigset_data[0]);
  218.       break;
  219.     default:
  220.       errno = EINVAL;
  221.       rv = -1;
  222.   }
  223.   if (oset) oset->_sigset_data[0] = omask;
  224.   return rv;
  225. }
  226.  
  227. int
  228. sigsuspend(sigmask)
  229.   const sigset_t *sigmask;
  230. {
  231.   Psigpause(sigmask->_sigset_data[0]);
  232.   errno = EINTR;
  233.   return -1;
  234. }
  235.