If a process exists but has a different uid than the killer it should return
[unix-history] / usr / src / sys / kern / kern_sig.c
index 527252d..07a8467 100644 (file)
@@ -1,4 +1,4 @@
-/*     kern_sig.c      5.19    83/06/02        */
+/*     kern_sig.c      6.2     83/09/08        */
 
 #include "../machine/reg.h"
 #include "../machine/pte.h"
 
 #include "../machine/reg.h"
 #include "../machine/pte.h"
 #include "../h/kernel.h"
 #include "../h/nami.h"
 
 #include "../h/kernel.h"
 #include "../h/nami.h"
 
+#define        mask(s) (1 << ((s)-1))
+#define        cantmask        (mask(SIGKILL)|mask(SIGCONT)|mask(SIGSTOP))
+
 sigvec()
 {
 sigvec()
 {
-       struct a {
+       register struct a {
                int     signo;
                int     signo;
-               int     (*sighandler)();
-               int     sigmask;
+               struct  sigvec *nsv;
+               struct  sigvec *osv;
        } *uap = (struct a  *)u.u_ap;
        } *uap = (struct a  *)u.u_ap;
+       struct sigvec vec;
+       register struct sigvec *sv;
        register int sig;
 
        sig = uap->signo;
        register int sig;
 
        sig = uap->signo;
-       if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP ||
-           (sig == SIGCONT && uap->sighandler == SIG_IGN)) {
+       if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) {
                u.u_error = EINVAL;
                return;
        }
                u.u_error = EINVAL;
                return;
        }
-       setsignal(sig, uap->sighandler, uap->sigmask);
+       sv = &vec;
+       if (uap->osv) {
+               sv->sv_handler = u.u_signal[sig];
+               sv->sv_mask = u.u_sigmask[sig];
+               sv->sv_onstack = (u.u_sigonstack & mask(sig)) != 0;
+               u.u_error =
+                   copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec));
+               if (u.u_error)
+                       return;
+       }
+       if (uap->nsv) {
+               u.u_error =
+                   copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec));
+               if (u.u_error)
+                       return;
+               if (sig == SIGCONT && sv->sv_handler == SIG_IGN) {
+                       u.u_error = EINVAL;
+                       return;
+               }
+               setsigvec(sig, sv);
+       }
 }
 
 }
 
-setsignal(sig, action, sigmask)
-       int sig, (*action)(), sigmask;
+setsigvec(sig, sv)
+       int sig;
+       register struct sigvec *sv;
 {
        register struct proc *p;
 {
        register struct proc *p;
-       register int mask;
+       register int bit;
 
 
-       u.u_r.r_val1 = (int)u.u_signal[sig];
-       mask = 1 << (sig - 1);
+       bit = mask(sig);
        p = u.u_procp;
        /*
         * Change setting atomically.
         */
        (void) spl6();
        p = u.u_procp;
        /*
         * Change setting atomically.
         */
        (void) spl6();
-       u.u_signal[sig] = action;
-       u.u_sigmask[sig] = sigmask;
-       if (action == SIG_IGN) {
-               p->p_sig &= ~mask;              /* never to be seen again */
-               p->p_sigignore |= mask;
-               p->p_sigcatch &= ~mask;
+       u.u_signal[sig] = sv->sv_handler;
+       u.u_sigmask[sig] = sv->sv_mask &~ cantmask;
+       if (sv->sv_onstack)
+               u.u_sigonstack |= bit;
+       else
+               u.u_sigonstack &= ~bit;
+       if (sv->sv_handler == SIG_IGN) {
+               p->p_sig &= ~bit;               /* never to be seen again */
+               p->p_sigignore |= bit;
+               p->p_sigcatch &= ~bit;
        } else {
        } else {
-               p->p_sigignore &= ~mask;
-               if (action == SIG_DFL)
-                       p->p_sigcatch &= ~mask;
+               p->p_sigignore &= ~bit;
+               if (sv->sv_handler == SIG_DFL)
+                       p->p_sigcatch &= ~bit;
                else
                else
-                       p->p_sigcatch |= mask;
+                       p->p_sigcatch |= bit;
        }
        (void) spl0();
 }
        }
        (void) spl0();
 }
@@ -73,33 +101,33 @@ setsignal(sig, action, sigmask)
 sigblock()
 {
        struct a {
 sigblock()
 {
        struct a {
-               int     mask;
+               int     sigmask;
        } *uap = (struct a *)u.u_ap;
        } *uap = (struct a *)u.u_ap;
-       struct proc *p = u.u_procp;
+       register struct proc *p = u.u_procp;
 
        (void) spl6();
        u.u_r.r_val1 = p->p_sigmask;
 
        (void) spl6();
        u.u_r.r_val1 = p->p_sigmask;
-       p->p_sigmask |= uap->mask;
+       p->p_sigmask |= uap->sigmask &~ cantmask;
        (void) spl0();
 }
 
 sigsetmask()
 {
        struct a {
        (void) spl0();
 }
 
 sigsetmask()
 {
        struct a {
-               int     mask;
+               int     sigmask;
        } *uap = (struct a *)u.u_ap;
        register struct proc *p = u.u_procp;
 
        (void) spl6();
        u.u_r.r_val1 = p->p_sigmask;
        } *uap = (struct a *)u.u_ap;
        register struct proc *p = u.u_procp;
 
        (void) spl6();
        u.u_r.r_val1 = p->p_sigmask;
-       p->p_sigmask = uap->mask;
+       p->p_sigmask = uap->sigmask &~ cantmask;
        (void) spl0();
 }
 
 sigpause()
 {
        struct a {
        (void) spl0();
 }
 
 sigpause()
 {
        struct a {
-               int     mask;
+               int     sigmask;
        } *uap = (struct a *)u.u_ap;
        register struct proc *p = u.u_procp;
 
        } *uap = (struct a *)u.u_ap;
        register struct proc *p = u.u_procp;
 
@@ -112,23 +140,38 @@ sigpause()
         */
        u.u_oldmask = p->p_sigmask;
        p->p_flag |= SOMASK;
         */
        u.u_oldmask = p->p_sigmask;
        p->p_flag |= SOMASK;
-       p->p_sigmask = uap->mask;
+       p->p_sigmask = uap->sigmask &~ cantmask;
        for (;;)
                sleep((caddr_t)&u, PSLEP);
        /*NOTREACHED*/
 }
        for (;;)
                sleep((caddr_t)&u, PSLEP);
        /*NOTREACHED*/
 }
+#undef cantmask
+#undef mask
 
 sigstack()
 {
 
 sigstack()
 {
-       struct a {
-               caddr_t asp;
-               int     onsigstack;
+       register struct a {
+               struct  sigstack *nss;
+               struct  sigstack *oss;
        } *uap = (struct a *)u.u_ap;
        } *uap = (struct a *)u.u_ap;
+       struct sigstack ss;
 
 
-       u.u_sigstack = uap->asp;
-       u.u_onsigstack = uap->onsigstack;
+       if (uap->oss) {
+               u.u_error = copyout((caddr_t)&u.u_sigstack, (caddr_t)uap->oss, 
+                   sizeof (struct sigstack));
+               if (u.u_error)
+                       return;
+       }
+       if (uap->nss) {
+               u.u_error =
+                   copyin((caddr_t)uap->nss, (caddr_t)&ss, sizeof (ss));
+               if (u.u_error == 0)
+                       u.u_sigstack = ss;
+       }
 }
 
 }
 
+/* KILL SHOULD BE UPDATED */
+
 kill()
 {
        register struct a {
 kill()
 {
        register struct a {
@@ -136,7 +179,8 @@ kill()
                int     signo;
        } *uap = (struct a *)u.u_ap;
 
                int     signo;
        } *uap = (struct a *)u.u_ap;
 
-       u.u_error = kill1(0, uap->signo, uap->pid);
+       u.u_error = kill1(uap->signo < 0,
+               uap->signo < 0 ? -uap->signo : uap->signo, uap->pid);
 }
 
 killpg()
 }
 
 killpg()
@@ -161,8 +205,10 @@ kill1(ispgrp, signo, who)
                return (EINVAL);
        if (who > 0 && !ispgrp) {
                p = pfind(who);
                return (EINVAL);
        if (who > 0 && !ispgrp) {
                p = pfind(who);
-               if (p == 0 || u.u_uid && u.u_uid != p->p_uid)
+               if (p == 0)
                        return (ESRCH);
                        return (ESRCH);
+               if (u.u_uid && u.u_uid != p->p_uid)
+                       return (EPERM);
                if (signo)
                        psignal(p, signo);
                return (0);
                if (signo)
                        psignal(p, signo);
                return (0);
@@ -458,9 +504,9 @@ issig()
 
        p = u.u_procp;
        for (;;) {
 
        p = u.u_procp;
        for (;;) {
-               sigbits = p->p_sig;
+               sigbits = p->p_sig &~ p->p_sigmask;
                if ((p->p_flag&STRC) == 0)
                if ((p->p_flag&STRC) == 0)
-                       sigbits &= ~(p->p_sigignore | p->p_sigmask);
+                       sigbits &= ~p->p_sigignore;
                if (p->p_flag&SVFORK)
 #define bit(a) (1<<(a-1))
                        sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU));
                if (p->p_flag&SVFORK)
 #define bit(a) (1<<(a-1))
                        sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU));
@@ -484,7 +530,7 @@ issig()
                         * If the traced bit got turned off,
                         * then put the signal taken above back into p_sig
                         * and go back up to the top to rescan signals.
                         * If the traced bit got turned off,
                         * then put the signal taken above back into p_sig
                         * and go back up to the top to rescan signals.
-                        * This ensures that siga0 and u_signal are consistent.
+                        * This ensures that p_sig* and u_signal are consistent.
                         */
                        if ((p->p_flag&STRC) == 0) {
                                p->p_sig |= sigmask;
                         */
                        if ((p->p_flag&STRC) == 0) {
                                p->p_sig |= sigmask;
@@ -499,6 +545,16 @@ issig()
                        sig = p->p_cursig;
                        if (sig == 0)
                                continue;
                        sig = p->p_cursig;
                        if (sig == 0)
                                continue;
+
+                       /*
+                        * If signal is being masked put it back
+                        * into p_sig and look for other signals.
+                        */
+                       sigmask = 1 << (sig-1);
+                       if (p->p_sigmask & sigmask) {
+                               p->p_sig |= sigmask;
+                               continue;
+                       }
                }
                switch (u.u_signal[sig]) {
 
                }
                switch (u.u_signal[sig]) {
 
@@ -533,6 +589,7 @@ issig()
                        case SIGCONT:
                        case SIGCHLD:
                        case SIGURG:
                        case SIGCONT:
                        case SIGCHLD:
                        case SIGURG:
+                       case SIGIO:
                                /*
                                 * These signals are normally not
                                 * sent if the action is the default.
                                /*
                                 * These signals are normally not
                                 * sent if the action is the default.
@@ -642,7 +699,7 @@ psig()
                        p->p_flag &= ~SOMASK;
                } else
                        returnmask = p->p_sigmask;
                        p->p_flag &= ~SOMASK;
                } else
                        returnmask = p->p_sigmask;
-               p->p_sigmask = u.u_sigmask[sig] | sigmask;
+               p->p_sigmask |= u.u_sigmask[sig] | sigmask;
                (void) spl0();
                u.u_ru.ru_nsignals++;
                sendsig(action, sig, returnmask);
                (void) spl0();
                u.u_ru.ru_nsignals++;
                sendsig(action, sig, returnmask);