home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / mint / mint095s / dossig.c < prev    next >
C/C++ Source or Header  |  1993-08-03  |  4KB  |  202 lines

  1. /*
  2. Copyright 1990,1991,1992 Eric R. Smith. All rights reserved.
  3. */
  4.  
  5. /* dossig.c:: dos signal handling routines */
  6.  
  7. #include "mint.h"
  8.  
  9. /*
  10.  * send a signal to another process. If pid > 0, send the signal just to
  11.  * that process. If pid < 0, send the signal to all processes whose process
  12.  * group is -pid. If pid == 0, send the signal to all processes with the
  13.  * same process group id.
  14.  *
  15.  * note: post_sig just posts the signal to the process.
  16.  */
  17.  
  18. long
  19. p_kill(pid, sig)
  20.     int pid, sig;
  21. {
  22.     PROC *p;
  23.  
  24.     TRACE("Pkill(%d, %d)", pid, sig);
  25.     if (sig < 0 || sig >= NSIG) {
  26.         DEBUG("Pkill: signal out of range");
  27.         return ERANGE;
  28.     }
  29.  
  30.     if (pid < 0)
  31.         return killgroup(-pid, sig);
  32.     else if (pid == 0)
  33.         return killgroup(curproc->pgrp, sig);
  34.     else {
  35.         p = pid2proc(pid);
  36.         if (p == 0 || p->wait_q == ZOMBIE_Q || p->wait_q == TSR_Q) {
  37.             DEBUG("Pkill: pid %d not found", pid);
  38.             return EFILNF;
  39.         }
  40.         if (curproc->euid && curproc->ruid != p->ruid) {
  41.             DEBUG("Pkill: wrong user");
  42.             return EACCDN;
  43.         }
  44.  
  45. /* if the user sends signal 0, don't deliver it -- for users, signal
  46.  * 0 is a null signal used to test the existence of a process
  47.  */
  48.         if (sig != 0)
  49.             post_sig(p, sig);
  50.     }
  51.  
  52.     check_sigs();
  53.     TRACE("Pkill: returning OK");
  54.     return 0;
  55. }
  56.  
  57. /*
  58.  * set a user-specified signal handler, POSIX.1 style
  59.  * "oact", if non-null, gets the old signal handling
  60.  * behaviour; "act", if non-null, specifies new
  61.  * behaviour
  62.  */
  63.  
  64. long
  65. p_sigaction(sig, act, oact)
  66.     int sig;
  67.     const struct sigaction *act;
  68.     struct sigaction *oact;
  69. {
  70.     TRACE("Psigaction(%d)", sig);
  71.     if (sig < 1 || sig >= NSIG)
  72.         return ERANGE;
  73.     if (act && (sig == SIGKILL || sig == SIGSTOP))
  74.         return EACCDN;
  75.     if (oact) {
  76.         oact->sa_handler = curproc->sighandle[sig];
  77.         oact->sa_mask = curproc->sigextra[sig];
  78.         oact->sa_flags = curproc->sigflags[sig];
  79.     }
  80.     if (act) {
  81.         curproc->sighandle[sig] = act->sa_handler;
  82.         curproc->sigextra[sig] = act->sa_mask & ~UNMASKABLE;
  83.         curproc->sigflags[sig] = act->sa_flags;
  84.  
  85. /* various special things that should happen */
  86.         if (act->sa_handler == SIG_IGN) {
  87.             /* discard pending signals */
  88.             curproc->sigpending &= ~(1L<<sig);
  89.         }
  90.  
  91. /* I dunno if this is right, but bash seems to expect it */
  92.          curproc->sigmask &= ~(1L<<sig);
  93.     }
  94.     return 0;
  95. }
  96.  
  97. /*
  98.  * set a user-specified signal handler
  99.  */
  100.  
  101. long
  102. p_signal(sig, handler)
  103.     int sig;
  104.     long handler;
  105. {
  106.     long oldhandle;
  107.  
  108.     TRACE("Psignal(%d, %lx)", sig, handler);
  109.     if (sig < 1 || sig >= NSIG)
  110.         return ERANGE;
  111.     if (sig == SIGKILL || sig == SIGSTOP)
  112.         return EACCDN;
  113.     oldhandle = curproc->sighandle[sig];
  114.     curproc->sighandle[sig] = handler;
  115.     curproc->sigextra[sig] = 0;
  116.     curproc->sigflags[sig] = 0;
  117.  
  118. /* various special things that should happen */
  119.     if (handler == SIG_IGN) {
  120.         /* discard pending signals */
  121.         curproc->sigpending &= ~(1L<<sig);
  122.     }
  123.  
  124. /* I dunno if this is right, but bash seems to expect it */
  125.     curproc->sigmask &= ~(1L<<sig);
  126.  
  127.     return oldhandle;
  128. }
  129.  
  130. /*
  131.  * block some signals. Returns the old signal mask.
  132.  */
  133.  
  134. long
  135. p_sigblock(mask)
  136.     ulong mask;
  137. {
  138.     ulong oldmask;
  139.  
  140.     TRACE("Psigblock(%lx)",mask);
  141. /* some signals (e.g. SIGKILL) can't be masked */
  142.     mask &= ~(UNMASKABLE);
  143.     oldmask = curproc->sigmask;
  144.     curproc->sigmask |= mask;
  145.     return oldmask;
  146. }
  147.  
  148. /*
  149.  * set the signals that we're blocking. Some signals (e.g. SIGKILL)
  150.  * can't be masked.
  151.  * Returns the old mask.
  152.  */
  153.  
  154. long
  155. p_sigsetmask(mask)
  156.     ulong mask;
  157. {
  158.     ulong oldmask;
  159.  
  160.     TRACE("Psigsetmask(%lx)",mask);
  161.     oldmask = curproc->sigmask;
  162.     curproc->sigmask = mask & ~(UNMASKABLE);
  163.     check_sigs();    /* maybe we unmasked something */
  164.     return oldmask;
  165. }
  166.  
  167. /*
  168.  * p_sigpending: return which signals are pending delivery
  169.  */
  170.  
  171. long
  172. p_sigpending()
  173. {
  174.     TRACE("Psigpending()");
  175.     check_sigs();    /* clear out any that are going to be delivered soon */
  176.     return curproc->sigpending;
  177. }
  178.  
  179. /*
  180.  * p_sigpause: atomically set the signals that we're blocking, then pause.
  181.  * Some signals (e.g. SIGKILL) can't be masked.
  182.  */
  183.  
  184. long
  185. p_sigpause(mask)
  186.     ulong mask;
  187. {
  188.     ulong oldmask;
  189.  
  190.     TRACE("Psigpause(%lx)", mask);
  191.     oldmask = curproc->sigmask;
  192.     curproc->sigmask = mask & ~(UNMASKABLE);
  193.     if (curproc->sigpending & ~(curproc->sigmask))
  194.         check_sigs();    /* a signal is immediately pending */
  195.     else
  196.         sleep(IO_Q, -1L);
  197.     curproc->sigmask = oldmask;
  198.     check_sigs();    /* maybe we unmasked something */
  199.     TRACE("Psigpause: returning OK");
  200.     return 0;
  201. }
  202.