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 a69b5bc..07a8467 100644 (file)
@@ -1,14 +1,15 @@
-/*     kern_sig.c      5.4     82/08/22        */
+/*     kern_sig.c      6.2     83/09/08        */
+
+#include "../machine/reg.h"
+#include "../machine/pte.h"
+#include "../machine/psl.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/dir.h"
 #include "../h/user.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/dir.h"
 #include "../h/user.h"
-#include "../h/reg.h"
 #include "../h/inode.h"
 #include "../h/proc.h"
 #include "../h/inode.h"
 #include "../h/proc.h"
-#include "../h/clock.h"
-#include "../h/mtpr.h"
 #include "../h/timeb.h"
 #include "../h/times.h"
 #include "../h/conf.h"
 #include "../h/timeb.h"
 #include "../h/times.h"
 #include "../h/conf.h"
 #include "../h/mount.h"
 #include "../h/text.h"
 #include "../h/seg.h"
 #include "../h/mount.h"
 #include "../h/text.h"
 #include "../h/seg.h"
-#include "../h/pte.h"
-#include "../h/psl.h"
 #include "../h/vm.h"
 #include "../h/vm.h"
-#include "../h/vlimit.h"
 #include "../h/acct.h"
 #include "../h/uio.h"
 #include "../h/acct.h"
 #include "../h/uio.h"
+#include "../h/kernel.h"
+#include "../h/nami.h"
 
 
-/* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */
+#define        mask(s) (1 << ((s)-1))
+#define        cantmask        (mask(SIGKILL)|mask(SIGCONT)|mask(SIGSTOP))
 
 sigvec()
 {
 
 sigvec()
 {
+       register struct a {
+               int     signo;
+               struct  sigvec *nsv;
+               struct  sigvec *osv;
+       } *uap = (struct a  *)u.u_ap;
+       struct sigvec vec;
+       register struct sigvec *sv;
+       register int sig;
 
 
+       sig = uap->signo;
+       if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) {
+               u.u_error = EINVAL;
+               return;
+       }
+       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);
+       }
+}
+
+setsigvec(sig, sv)
+       int sig;
+       register struct sigvec *sv;
+{
+       register struct proc *p;
+       register int bit;
+
+       bit = mask(sig);
+       p = u.u_procp;
+       /*
+        * Change setting atomically.
+        */
+       (void) spl6();
+       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 {
+               p->p_sigignore &= ~bit;
+               if (sv->sv_handler == SIG_DFL)
+                       p->p_sigcatch &= ~bit;
+               else
+                       p->p_sigcatch |= bit;
+       }
+       (void) spl0();
 }
 
 sigblock()
 {
 }
 
 sigblock()
 {
+       struct a {
+               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;
+       p->p_sigmask |= uap->sigmask &~ cantmask;
+       (void) spl0();
 }
 
 sigsetmask()
 {
 }
 
 sigsetmask()
 {
+       struct a {
+               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;
+       p->p_sigmask = uap->sigmask &~ cantmask;
+       (void) spl0();
 }
 
 sigpause()
 {
 }
 
 sigpause()
 {
+       struct a {
+               int     sigmask;
+       } *uap = (struct a *)u.u_ap;
+       register struct proc *p = u.u_procp;
 
 
+       /*
+        * When returning from sigpause, we want
+        * the old mask to be restored after the
+        * signal handler has finished.  Thus, we
+        * save it here and mark the proc structure
+        * to indicate this (should be in u.).
+        */
+       u.u_oldmask = p->p_sigmask;
+       p->p_flag |= SOMASK;
+       p->p_sigmask = uap->sigmask &~ cantmask;
+       for (;;)
+               sleep((caddr_t)&u, PSLEP);
+       /*NOTREACHED*/
 }
 }
+#undef cantmask
+#undef mask
 
 sigstack()
 {
 
 sigstack()
 {
-
+       register struct a {
+               struct  sigstack *nss;
+               struct  sigstack *oss;
+       } *uap = (struct a *)u.u_ap;
+       struct sigstack ss;
+
+       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;
+       }
 }
 
 }
 
-/* BEGIN DEFUNCT */
-okill()
+/* KILL SHOULD BE UPDATED */
+
+kill()
 {
 {
-       register struct proc *p;
-       register a, sig;
        register struct a {
                int     pid;
                int     signo;
        register struct a {
                int     pid;
                int     signo;
-       } *uap;
-       int f, priv;
+       } *uap = (struct a *)u.u_ap;
 
 
-       uap = (struct a *)u.u_ap;
-       f = 0;
-       a = uap->pid;
-       priv = 0;
-       sig = uap->signo;
-       if (sig < 0)
-               /*
-                * A negative signal means send to process group.
-                */
-               uap->signo = -uap->signo;
-       if (uap->signo == 0 || uap->signo > NSIG) {
-               u.u_error = EINVAL;
-               return;
-       }
-       if (a > 0 && sig > 0) {
-               p = pfind(a);
-               if (p == 0 || u.u_uid && u.u_uid != p->p_uid) {
-                       u.u_error = ESRCH;
-                       return;
-               }
-               psignal(p, uap->signo);
-               return;
+       u.u_error = kill1(uap->signo < 0,
+               uap->signo < 0 ? -uap->signo : uap->signo, uap->pid);
+}
+
+killpg()
+{
+       register struct a {
+               int     pgrp;
+               int     signo;
+       } *uap = (struct a *)u.u_ap;
+
+       u.u_error = kill1(1, uap->signo, uap->pgrp);
+}
+
+/* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */
+
+kill1(ispgrp, signo, who)
+       int ispgrp, signo, who;
+{
+       register struct proc *p;
+       int f, priv = 0;
+
+       if (signo < 0 || signo > NSIG)
+               return (EINVAL);
+       if (who > 0 && !ispgrp) {
+               p = pfind(who);
+               if (p == 0)
+                       return (ESRCH);
+               if (u.u_uid && u.u_uid != p->p_uid)
+                       return (EPERM);
+               if (signo)
+                       psignal(p, signo);
+               return (0);
        }
        }
-       if (a==-1 && u.u_uid==0) {
-               priv++;
-               a = 0;
-               sig = -1;               /* like sending to pgrp */
-       } else if (a==0) {
+       if (who == -1 && u.u_uid == 0)
+               priv++, who = 0, ispgrp = 1;    /* like sending to pgrp */
+       else if (who == 0) {
                /*
                 * Zero process id means send to my process group.
                 */
                /*
                 * Zero process id means send to my process group.
                 */
-               sig = -1;
-               a = u.u_procp->p_pgrp;
-               if (a == 0) {
-                       u.u_error = EINVAL;
-                       return;
-               }
+               ispgrp = 1;
+               who = u.u_procp->p_pgrp;
+               if (who == 0)
+                       return (EINVAL);
        }
        }
-       for(p = proc; p < procNPROC; p++) {
+       for (f = 0, p = proc; p < procNPROC; p++) {
                if (p->p_stat == NULL)
                        continue;
                if (p->p_stat == NULL)
                        continue;
-               if (sig > 0) {
-                       if (p->p_pid != a)
+               if (!ispgrp) {
+                       if (p->p_pid != who)
                                continue;
                                continue;
-               } else if (p->p_pgrp!=a && priv==0 || p->p_ppid==0 ||
-                   (p->p_flag&SSYS) || (priv && p==u.u_procp))
+               } else if (p->p_pgrp != who && priv == 0 || p->p_ppid == 0 ||
+                   (p->p_flag&SSYS) || (priv && p == u.u_procp))
                        continue;
                if (u.u_uid != 0 && u.u_uid != p->p_uid &&
                        continue;
                if (u.u_uid != 0 && u.u_uid != p->p_uid &&
-                   (uap->signo != SIGCONT || !inferior(p)))
+                   (signo != SIGCONT || !inferior(p)))
                        continue;
                f++;
                        continue;
                f++;
-               psignal(p, uap->signo);
+               if (signo)
+                       psignal(p, signo);
        }
        }
-       if (f == 0)
-               u.u_error = ESRCH;
-}
-
-ossig()
-{
-       register int (*f)();
-       struct a {
-               int     signo;
-               int     (*fun)();
-       } *uap;
-       register struct proc *p = u.u_procp;
-       register a;
-       long sigmask;
-
-       uap = (struct a *)u.u_ap;
-       a = uap->signo & SIGNUMMASK;
-       f = uap->fun;
-       if (a<=0 || a>=NSIG || a==SIGKILL || a==SIGSTOP ||
-           a==SIGCONT && (f == SIG_IGN || f == SIG_HOLD)) {
-               u.u_error = EINVAL;
-               return;
-       }
-       if ((uap->signo &~ SIGNUMMASK) || (f != SIG_DFL && f != SIG_IGN &&
-           SIGISDEFER(f)))
-               u.u_procp->p_flag |= SNUSIG;
-       /* 
-        * Don't clobber registers if we are to simulate
-        * a ret+rti.
-        */
-       if ((uap->signo&SIGDORTI) == 0)
-               u.u_r.r_val1 = (int)u.u_signal[a];
-       /*
-        * Change setting atomically.
-        */
-       (void) spl6();
-       sigmask = 1L << (a-1);
-       if (u.u_signal[a] == SIG_IGN)
-               p->p_sig &= ~sigmask;           /* never to be seen again */
-       u.u_signal[a] = f;
-       if (f != SIG_DFL && f != SIG_IGN && f != SIG_HOLD)
-               f = SIG_CATCH;
-       if ((int)f & 1)
-               p->p_siga0 |= sigmask;
-       else
-               p->p_siga0 &= ~sigmask;
-       if ((int)f & 2)
-               p->p_siga1 |= sigmask;
-       else
-               p->p_siga1 &= ~sigmask;
-       (void) spl0();
-       /*
-        * Now handle options.
-        */
-       if (uap->signo & SIGDOPAUSE) {
-               /*
-                * Simulate a PDP11 style wait instrution which
-                * atomically lowers priority, enables interrupts
-                * and hangs.
-                */
-               opause();
-               /*NOTREACHED*/
-       }
-       if (uap->signo & SIGDORTI)
-               u.u_eosys = SIMULATERTI;
+       return (f == 0 ? ESRCH : 0);
 }
 
 /*
  * Send the specified signal to
  * all processes with 'pgrp' as
  * process group.
 }
 
 /*
  * Send the specified signal to
  * all processes with 'pgrp' as
  * process group.
- * Called by tty.c for quits and
- * interrupts.
  */
 gsignal(pgrp, sig)
        register int pgrp;
  */
 gsignal(pgrp, sig)
        register int pgrp;
@@ -210,28 +270,30 @@ psignal(p, sig)
 {
        register int s;
        register int (*action)();
 {
        register int s;
        register int (*action)();
-       long sigmask;
+       int sigmask;
 
        if ((unsigned)sig >= NSIG)
                return;
 
        if ((unsigned)sig >= NSIG)
                return;
-       sigmask = (1L << (sig-1));
+       sigmask = 1 << (sig-1);
 
        /*
         * If proc is traced, always give parent a chance.
 
        /*
         * If proc is traced, always give parent a chance.
-        * Otherwise get the signal action from the bits in the proc table.
         */
        if (p->p_flag & STRC)
                action = SIG_DFL;
        else {
         */
        if (p->p_flag & STRC)
                action = SIG_DFL;
        else {
-               s = (p->p_siga1&sigmask) != 0;
-               s <<= 1;
-               s |= (p->p_siga0&sigmask) != 0;
-               action = (int(*)())s;
                /*
                /*
-                * If the signal is ignored, we forget about it immediately.
+                * If the signal is being ignored,
+                * then we forget about it immediately.
                 */
                 */
-               if (action == SIG_IGN)
+               if (p->p_sigignore & sigmask)
                        return;
                        return;
+               if (p->p_sigmask & sigmask)
+                       action = SIG_HOLD;
+               else if (p->p_sigcatch & sigmask)
+                       action = SIG_CATCH;
+               else
+                       action = SIG_DFL;
        }
 #define mask(sig)      (1<<(sig-1))
 #define        stops   (mask(SIGSTOP)|mask(SIGTSTP)|mask(SIGTTIN)|mask(SIGTTOU))
        }
 #define mask(sig)      (1<<(sig-1))
 #define        stops   (mask(SIGSTOP)|mask(SIGTSTP)|mask(SIGTTIN)|mask(SIGTTOU))
@@ -240,7 +302,7 @@ psignal(p, sig)
                switch (sig) {
 
                case SIGTERM:
                switch (sig) {
 
                case SIGTERM:
-                       if ((p->p_flag&STRC) != 0 || action != SIG_DFL)
+                       if ((p->p_flag&STRC) || action != SIG_DFL)
                                break;
                        /* fall into ... */
 
                                break;
                        /* fall into ... */
 
@@ -400,6 +462,7 @@ psignal(p, sig)
                 * It will either never be noticed, or noticed very soon.
                 */
                if (p == u.u_procp && !noproc)
                 * It will either never be noticed, or noticed very soon.
                 */
                if (p == u.u_procp && !noproc)
+#include "../vax/mtpr.h"
                        aston();
                goto out;
        }
                        aston();
                goto out;
        }
@@ -437,24 +500,23 @@ issig()
 {
        register struct proc *p;
        register int sig;
 {
        register struct proc *p;
        register int sig;
-       long sigbits;
-       long sigmask;
+       int sigbits, sigmask;
 
        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_ignsig;
+                       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 (sigbits == 0)
                        break;
                if (p->p_flag&SVFORK)
 #define bit(a) (1<<(a-1))
                        sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU));
                if (sigbits == 0)
                        break;
-               sig = ffs((int)sigbits);
-               sigmask = 1L << (sig-1);
+               sig = ffs(sigbits);
+               sigmask = 1 << (sig-1);
                p->p_sig &= ~sigmask;           /* take the signal! */
                p->p_cursig = sig;
                p->p_sig &= ~sigmask;           /* take the signal! */
                p->p_cursig = sig;
-               if (p->p_flag&STRC && (p->p_flag&SVFORK)==0) {
+               if (p->p_flag&STRC && (p->p_flag&SVFORK) == 0) {
                        /*
                         * If traced, always stop, and stay
                         * stopped until released by the parent.
                        /*
                         * If traced, always stop, and stay
                         * stopped until released by the parent.
@@ -468,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;
@@ -483,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]) {
 
@@ -516,6 +588,8 @@ issig()
 
                        case SIGCONT:
                        case SIGCHLD:
 
                        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.
@@ -590,44 +664,50 @@ stop(p)
  */
 psig()
 {
  */
 psig()
 {
-       register struct proc *rp = u.u_procp;
-       register int n = rp->p_cursig;
-       long sigmask = 1L << (n-1);
+       register struct proc *p = u.u_procp;
+       register int sig = p->p_cursig;
+       int sigmask = 1 << (sig - 1), returnmask;
        register int (*action)();
 
        register int (*action)();
 
-       if (rp->p_cursig == 0)
+       if (sig == 0)
                panic("psig");
                panic("psig");
-       action = u.u_signal[n];
+       action = u.u_signal[sig];
        if (action != SIG_DFL) {
        if (action != SIG_DFL) {
-               if (action == SIG_IGN || action == SIG_HOLD)
+               if (action == SIG_IGN || (p->p_sigmask & sigmask))
                        panic("psig action");
                u.u_error = 0;
                        panic("psig action");
                u.u_error = 0;
-               if (n != SIGILL && n != SIGTRAP)
-                       u.u_signal[n] = 0;
                /*
                /*
-                * If this catch value indicates automatic holding of
-                * subsequent signals, set the hold value.
+                * Set the new mask value and also defer further
+                * occurences of this signal (unless we're simulating
+                * the old signal facilities). 
+                *
+                * Special case: user has done a sigpause.  Here the
+                * current mask is not of interest, but rather the
+                * mask from before the sigpause is what we want restored
+                * after the signal processing is completed.
                 */
                 */
-               if (SIGISDEFER(action)) {
-                       (void) spl6();
-                       if ((int)SIG_HOLD & 1)
-                               rp->p_siga0 |= sigmask;
-                       else
-                               rp->p_siga0 &= ~sigmask;
-                       if ((int)SIG_HOLD & 2)
-                               rp->p_siga1 |= sigmask;
-                       else
-                               rp->p_siga1 &= ~sigmask;
-                       u.u_signal[n] = SIG_HOLD;
-                       (void) spl0();
-                       action = SIGUNDEFER(action);
+               (void) spl6();
+               if (p->p_flag & SOUSIG) {
+                       if (sig != SIGILL && sig != SIGTRAP) {
+                               u.u_signal[sig] = SIG_DFL;
+                               p->p_sigcatch &= ~sigmask;
+                       }
+                       sigmask = 0;
                }
                }
-               sendsig(action, n);
-               rp->p_cursig = 0;
+               if (p->p_flag & SOMASK) {
+                       returnmask = u.u_oldmask;
+                       p->p_flag &= ~SOMASK;
+               } else
+                       returnmask = p->p_sigmask;
+               p->p_sigmask |= u.u_sigmask[sig] | sigmask;
+               (void) spl0();
+               u.u_ru.ru_nsignals++;
+               sendsig(action, sig, returnmask);
+               p->p_cursig = 0;
                return;
        }
        u.u_acflag |= AXSIG;
                return;
        }
        u.u_acflag |= AXSIG;
-       switch (n) {
+       switch (sig) {
 
        case SIGILL:
        case SIGIOT:
 
        case SIGILL:
        case SIGIOT:
@@ -638,16 +718,13 @@ psig()
        case SIGFPE:
        case SIGSEGV:
        case SIGSYS:
        case SIGFPE:
        case SIGSEGV:
        case SIGSYS:
-               u.u_arg[0] = n;
+               u.u_arg[0] = sig;
                if (core())
                if (core())
-                       n += 0200;
+                       sig += 0200;
        }
        }
-       exit(n);
+       exit(sig);
 }
 
 }
 
-#ifdef unneeded
-int    corestop = 0;
-#endif
 /*
  * Create a core image on the file "core"
  * If you are looking for protection glitches,
 /*
  * Create a core image on the file "core"
  * If you are looking for protection glitches,
@@ -663,28 +740,18 @@ core()
        register struct inode *ip;
        extern schar();
 
        register struct inode *ip;
        extern schar();
 
-#ifdef unneeded
-       if (corestop) {
-               int i;
-               for (i = 0; i < 10; i++)
-                       if (u.u_comm[i])
-                               putchar(u.u_comm[i], 0);
-               printf(", uid %d\n", u.u_uid);
-               if (corestop&2)
-                       asm("halt");
-       }
-#endif
-       if (u.u_uid != u.u_ruid)
+       if (u.u_uid != u.u_ruid || u.u_gid != u.u_rgid)
                return (0);
                return (0);
-       if (ctob(UPAGES+u.u_dsize+u.u_ssize) >= u.u_limit[LIM_CORE])
+       if (ctob(UPAGES+u.u_dsize+u.u_ssize) >=
+           u.u_rlimit[RLIMIT_CORE].rlim_cur)
                return (0);
        u.u_error = 0;
        u.u_dirp = "core";
                return (0);
        u.u_error = 0;
        u.u_dirp = "core";
-       ip = namei(schar, 1, 1);
+       ip = namei(schar, CREATE, 1);
        if (ip == NULL) {
                if (u.u_error)
                        return (0);
        if (ip == NULL) {
                if (u.u_error)
                        return (0);
-               ip = maknode(0666);
+               ip = maknode(0644);
                if (ip==NULL)
                        return (0);
        }
                if (ip==NULL)
                        return (0);
        }
@@ -694,50 +761,23 @@ core()
                u.u_error = EFAULT;
                goto out;
        }
                u.u_error = EFAULT;
                goto out;
        }
-       itrunc(ip, 0);
+       itrunc(ip, (u_long)0);
        u.u_acflag |= ACORE;
        u.u_acflag |= ACORE;
-       u.u_error =rdwri(UIO_WRITE, ip,
-           (caddr_t)&u, ctob(UPAGES),
+       u.u_error = rdwri(UIO_WRITE, ip,
+           (caddr_t)&u,
+           ctob(UPAGES),
            0, 1, (int *)0);
            0, 1, (int *)0);
-       if (u.u_error)
-       rdwri(UIO_WRITE, ip,
-           (caddr_t)ctob(u.u_tsize), ctob(u.u_dsize),
-           ctob(UPAGES), 0, (int *)0);
-       if (u.u_error)
-       rdwri(UIO_WRITE, ip,
-           (caddr_t)(USRSTACK-ctob(u.u_ssize)), ctob(u.u_ssize),
-           ctob(UPAGES)+ctob(u.u_dsize), 0, (int *)0);
+       if (u.u_error == 0)
+               u.u_error = rdwri(UIO_WRITE, ip,
+                   (caddr_t)ctob(dptov(u.u_procp, 0)),
+                   ctob(u.u_dsize),
+                   ctob(UPAGES), 0, (int *)0);
+       if (u.u_error == 0)
+               u.u_error = rdwri(UIO_WRITE, ip,
+                   (caddr_t)ctob(sptov(u.u_procp, u.u_ssize - 1)),
+                   ctob(u.u_ssize),
+                   ctob(UPAGES)+ctob(u.u_dsize), 0, (int *)0);
 out:
        iput(ip);
        return (u.u_error == 0);
 }
 out:
        iput(ip);
        return (u.u_error == 0);
 }
-
-/*
- * alarm clock signal
- */
-oalarm()
-{
-       register struct proc *p;
-       register c;
-       register struct a {
-               int     deltat;
-       } *uap;
-
-       uap = (struct a *)u.u_ap;
-       p = u.u_procp;
-       c = p->p_clktim;
-       p->p_clktim = uap->deltat;
-       u.u_r.r_val1 = c;
-}
-
-/*
- * indefinite wait.
- * no one should wakeup(&u)
- */
-opause()
-{
-
-       for (;;)
-               sleep((caddr_t)&u, PSLEP);
-}
-