-/* kern_exec.c 4.2 83/06/02 */
+/*
+ * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)kern_exec.c 7.10 (Berkeley) %G%
+ */
-#include "../machine/reg.h"
-#include "../machine/pte.h"
-#include "../machine/psl.h"
+#include "param.h"
+#include "systm.h"
+#include "map.h"
+#include "user.h"
+#include "kernel.h"
+#include "proc.h"
+#include "mount.h"
+#include "ucred.h"
+#include "malloc.h"
+#include "buf.h"
+#include "vnode.h"
+#include "seg.h"
+#include "vm.h"
+#include "text.h"
+#include "file.h"
+#include "uio.h"
+#include "acct.h"
+#include "exec.h"
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/map.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/kernel.h"
-#include "../h/proc.h"
-#include "../h/buf.h"
-#include "../h/inode.h"
-#include "../h/seg.h"
-#include "../h/vm.h"
-#include "../h/text.h"
-#include "../h/file.h"
-#include "../h/uio.h"
-#include "../h/nami.h"
-#include "../h/acct.h"
+#include "machine/reg.h"
+#include "machine/pte.h"
+#include "machine/psl.h"
+#include "machine/mtpr.h"
/*
* exec system call, with and without environments.
register nc;
register char *cp;
register struct buf *bp;
+ struct buf *tbp;
register struct execa *uap;
- int na, ne, ucp, ap, c;
+ int na, ne, ucp, ap, cc;
+ unsigned len;
int indir, uid, gid;
char *sharg;
- struct inode *ip;
+ struct vnode *vp;
swblk_t bno;
+ struct vattr vattr;
char cfname[MAXCOMLEN + 1];
- char cfarg[SHSIZE];
- int resid;
+ char cfarg[MAXINTERP];
+ union {
+ char ex_shell[MAXINTERP]; /* #! and interpreter name */
+ struct exec ex_exec;
+ } exdata;
+ register struct nameidata *ndp = &u.u_nd;
+ int resid, error;
+#ifdef SECSIZE
+ extern long argdbsize; /* XXX */
+#endif SECSIZE
- if ((ip = namei(uchar, LOOKUP, 1)) == NULL)
+ ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
+ ndp->ni_segflg = UIO_USERSPACE;
+ ndp->ni_dirp = ((struct execa *)u.u_ap)->fname;
+ if (u.u_error = namei(ndp)) {
return;
+ }
+ vp = ndp->ni_vp;
bno = 0;
bp = 0;
indir = 0;
uid = u.u_uid;
gid = u.u_gid;
- if (ip->i_mode & ISUID)
- uid = ip->i_uid;
- if (ip->i_mode & ISGID)
- gid = ip->i_gid;
+ if (u.u_error = VOP_GETATTR(vp, &vattr, u.u_cred))
+ goto bad;
+ if (vp->v_mount->m_flag & M_NOEXEC) {
+ u.u_error = ENOEXEC;
+ goto bad;
+ }
+ if ((vp->v_mount->m_flag & M_NOSUID) == 0) {
+ if (vattr.va_mode & VSUID)
+ uid = vattr.va_uid;
+ if (vattr.va_mode & VSGID)
+ gid = vattr.va_gid;
+ }
again:
- if (access(ip, IEXEC))
+ if (u.u_error = vn_access(vp, VEXEC, u.u_cred))
goto bad;
- if ((u.u_procp->p_flag&STRC) && access(ip, IREAD))
+ if ((u.u_procp->p_flag & STRC) &&
+ (u.u_error = vn_access(vp, VREAD, u.u_cred)))
goto bad;
- if ((ip->i_mode & IFMT) != IFREG ||
- (ip->i_mode & (IEXEC|(IEXEC>>3)|(IEXEC>>6))) == 0) {
+ if (vp->v_type != VREG ||
+ (vattr.va_mode & (VEXEC|(VEXEC>>3)|(VEXEC>>6))) == 0) {
u.u_error = EACCES;
goto bad;
}
/*
- * Read in first few bytes of file for segment sizes, ux_mag:
- * 407 = plain executable
- * 410 = RO text
- * 413 = demand paged RO text
+ * Read in first few bytes of file for segment sizes, magic number:
+ * OMAGIC = plain executable
+ * NMAGIC = RO text
+ * ZMAGIC = demand paged RO text
* Also an ASCII line beginning with #! is
* the file name of a ``shell'' and arguments may be prepended
* to the argument list if given here.
* ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM
* THE ASCII LINE.
*/
- u.u_exdata.ux_shell[0] = 0; /* for zero length files */
- u.u_error = rdwri(UIO_READ, ip, (caddr_t)&u.u_exdata, sizeof (u.u_exdata),
- 0, 1, &resid);
+ exdata.ex_shell[0] = '\0'; /* for zero length files */
+ u.u_error = vn_rdwr(UIO_READ, vp, (caddr_t)&exdata, sizeof (exdata),
+ (off_t)0, UIO_SYSSPACE, (IO_UNIT|IO_NODELOCKED), u.u_cred, &resid);
if (u.u_error)
goto bad;
- u.u_count = resid;
#ifndef lint
- if (u.u_count > sizeof(u.u_exdata) - sizeof(u.u_exdata.Ux_A) &&
- u.u_exdata.ux_shell[0] != '#') {
+ if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) &&
+ exdata.ex_shell[0] != '#') {
u.u_error = ENOEXEC;
goto bad;
}
#endif
- switch (u.u_exdata.ux_mag) {
+ switch ((int)exdata.ex_exec.a_magic) {
- case 0407:
- u.u_exdata.ux_dsize += u.u_exdata.ux_tsize;
- u.u_exdata.ux_tsize = 0;
+ case OMAGIC:
+ exdata.ex_exec.a_data += exdata.ex_exec.a_text;
+ exdata.ex_exec.a_text = 0;
break;
- case 0413:
- case 0410:
- if (u.u_exdata.ux_tsize == 0) {
+ case ZMAGIC:
+ case NMAGIC:
+ if (exdata.ex_exec.a_text == 0) {
u.u_error = ENOEXEC;
goto bad;
}
break;
default:
- if (u.u_exdata.ux_shell[0] != '#' ||
- u.u_exdata.ux_shell[1] != '!' ||
+ if (exdata.ex_shell[0] != '#' ||
+ exdata.ex_shell[1] != '!' ||
indir) {
u.u_error = ENOEXEC;
goto bad;
}
- cp = &u.u_exdata.ux_shell[2]; /* skip "#!" */
- while (cp < &u.u_exdata.ux_shell[SHSIZE]) {
- if (*cp == '\t')
- *cp = ' ';
- else if (*cp == '\n') {
+ for (cp = &exdata.ex_shell[2];; ++cp) {
+ if (cp >= &exdata.ex_shell[MAXINTERP]) {
+ u.u_error = ENOEXEC;
+ goto bad;
+ }
+ if (*cp == '\n') {
*cp = '\0';
break;
}
- cp++;
- }
- if (*cp != '\0') {
- u.u_error = ENOEXEC;
- goto bad;
+ if (*cp == '\t')
+ *cp = ' ';
}
- cp = &u.u_exdata.ux_shell[2];
+ cp = &exdata.ex_shell[2];
while (*cp == ' ')
cp++;
- u.u_dirp = cp;
+ ndp->ni_dirp = cp;
while (*cp && *cp != ' ')
cp++;
- sharg = NULL;
+ cfarg[0] = '\0';
if (*cp) {
*cp++ = '\0';
while (*cp == ' ')
cp++;
- if (*cp) {
- bcopy((caddr_t)cp, (caddr_t)cfarg, SHSIZE);
- sharg = cfarg;
- }
+ if (*cp)
+ bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP);
}
- if (u.u_dent.d_namlen > MAXCOMLEN)
- u.u_dent.d_namlen = MAXCOMLEN;
- bcopy((caddr_t)u.u_dent.d_name, (caddr_t)cfname,
- (unsigned)(u.u_dent.d_namlen + 1));
- cfname[MAXCOMLEN] = 0;
indir = 1;
- iput(ip);
- ip = namei(schar, LOOKUP, 1);
- if (ip == NULL)
+ vput(vp);
+ ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
+ ndp->ni_segflg = UIO_SYSSPACE;
+ if (u.u_error = namei(ndp))
return;
+ vp = ndp->ni_vp;
+ if (u.u_error = VOP_GETATTR(vp, &vattr, u.u_cred))
+ goto bad;
+ bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname,
+ MAXCOMLEN);
+ cfname[MAXCOMLEN] = '\0';
+ uid = u.u_uid; /* shell scripts can't be setuid */
+ gid = u.u_gid;
goto again;
}
na = 0;
ne = 0;
nc = 0;
+ cc = 0;
uap = (struct execa *)u.u_ap;
- if ((bno = rmalloc(argmap, (long)ctod(clrnd((int)btoc(NCARGS))))) == 0) {
- swkill(u.u_procp, "exece");
+#ifdef SECSIZE
+ bno = rmalloc(argmap, (clrnd((int)btoc(NCARGS))) * CLBYTES / argdbsize);
+#else SECSIZE
+ bno = rmalloc(argmap, (long)ctod(clrnd((int)btoc(NCARGS))));
+#endif SECSIZE
+ if (bno == 0) {
+ swkill(u.u_procp, "exec: no swap space");
goto bad;
}
if (bno % CLSIZE)
panic("execa rmalloc");
+ /*
+ * Copy arguments into file in argdev area.
+ */
if (uap->argp) for (;;) {
ap = NULL;
- if (indir && (na == 1 || na == 2 && sharg))
+ sharg = NULL;
+ if (indir && na == 0) {
+ sharg = cfname;
+ ap = (int)sharg;
+ uap->argp++; /* ignore argv[0] */
+ } else if (indir && (na == 1 && cfarg[0])) {
+ sharg = cfarg;
+ ap = (int)sharg;
+ } else if (indir && (na == 1 || na == 2 && cfarg[0]))
ap = (int)uap->fname;
else if (uap->argp) {
ap = fuword((caddr_t)uap->argp);
uap->argp++;
}
- if (ap==NULL && uap->envp) {
+ if (ap == NULL && uap->envp) {
uap->argp = NULL;
- if ((ap = fuword((caddr_t)uap->envp)) == NULL)
- break;
- uap->envp++;
- ne++;
+ if ((ap = fuword((caddr_t)uap->envp)) != NULL)
+ uap->envp++, ne++;
}
if (ap == NULL)
break;
na++;
- if (ap == -1)
+ if (ap == -1) {
u.u_error = EFAULT;
+ break;
+ }
do {
- if (nc >= NCARGS-1)
- u.u_error = E2BIG;
- if (indir && na == 2 && sharg != NULL)
- c = *sharg++ & 0377;
- else if ((c = fubyte((caddr_t)ap++)) < 0)
- u.u_error = EFAULT;
- if (u.u_error) {
- if (bp)
- brelse(bp);
- bp = 0;
- goto badarg;
- }
- if (nc % (CLSIZE*NBPG) == 0) {
+ if (cc <= 0) {
+ /*
+ * We depend on NCARGS being a multiple of
+ * CLBYTES. This way we need only check
+ * overflow before each buffer allocation.
+ */
+ if (nc >= NCARGS-1) {
+ error = E2BIG;
+ break;
+ }
if (bp)
bdwrite(bp);
- bp = getblk(argdev, bno + ctod(nc / NBPG),
- CLSIZE*NBPG);
+ cc = CLBYTES;
+#ifdef SECSIZE
+ bp = getblk(argdev, bno + nc / argdbsize, cc,
+ argdbsize);
+#else SECSIZE
+ bp = getblk(argdev_vp, bno + ctod(nc/NBPG), cc);
+#endif SECSIZE
cp = bp->b_un.b_addr;
}
- nc++;
- *cp++ = c;
- } while (c > 0);
+ if (sharg) {
+ error = copystr(sharg, cp, (unsigned)cc, &len);
+ sharg += len;
+ } else {
+ error = copyinstr((caddr_t)ap, cp, (unsigned)cc,
+ &len);
+ ap += len;
+ }
+ cp += len;
+ nc += len;
+ cc -= len;
+ } while (error == ENOENT);
+ if (error) {
+ u.u_error = error;
+ if (bp)
+ brelse(bp);
+ bp = 0;
+ goto badarg;
+ }
}
if (bp)
bdwrite(bp);
bp = 0;
nc = (nc + NBPW-1) & ~(NBPW-1);
- if (indir) {
- u.u_dent.d_namlen = strlen(cfname);
- bcopy((caddr_t)cfname, (caddr_t)u.u_dent.d_name,
- (unsigned)(u.u_dent.d_namlen + 1));
- }
- getxfile(ip, nc + (na+4)*NBPW, uid, gid);
+ getxfile(vp, &exdata.ex_exec, nc + (na+4)*NBPW, uid, gid, u.u_cred);
if (u.u_error) {
badarg:
- for (c = 0; c < nc; c += CLSIZE*NBPG) {
- bp = baddr(argdev, bno + ctod(c / NBPG), CLSIZE*NBPG);
+ for (cc = 0; cc < nc; cc += CLBYTES) {
+ u.u_error = baddr(argdev_vp, bno + ctod(cc/NBPG),
+ CLBYTES, &tbp);
+ bp = tbp;
+#endif SECSIZE
if (bp) {
bp->b_flags |= B_AGE; /* throw away */
bp->b_flags &= ~B_DELWRI; /* cancel io */
}
goto bad;
}
+ vput(vp);
+ vp = NULL;
/*
- * copy back arglist
+ * Copy back arglist.
*/
ucp = USRSTACK - nc - NBPW;
ap = ucp - na*NBPW - 3*NBPW;
u.u_ar0[SP] = ap;
(void) suword((caddr_t)ap, na-ne);
nc = 0;
+ cc = 0;
for (;;) {
ap += NBPW;
- if (na==ne) {
+ if (na == ne) {
(void) suword((caddr_t)ap, 0);
ap += NBPW;
}
break;
(void) suword((caddr_t)ap, ucp);
do {
- if (nc % (CLSIZE*NBPG) == 0) {
+ if (cc <= 0) {
if (bp)
brelse(bp);
- bp = bread(argdev, bno + ctod(nc / NBPG),
- CLSIZE*NBPG);
+ cc = CLBYTES;
+#ifdef SECSIZE
+ bp = bread(argdev, bno + nc / argdbsize, cc,
+ argdbsize);
+#else SECSIZE
+ error = bread(argdev_vp,
+ (daddr_t)(bno + ctod(nc / NBPG)), cc, &tbp);
+ bp = tbp;
+#endif SECSIZE
bp->b_flags |= B_AGE; /* throw away */
bp->b_flags &= ~B_DELWRI; /* cancel io */
cp = bp->b_un.b_addr;
}
- (void) subyte((caddr_t)ucp++, (c = *cp++));
- nc++;
- } while(c&0377);
+ error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc,
+ &len);
+ ucp += len;
+ cp += len;
+ nc += len;
+ cc -= len;
+ } while (error == ENOENT);
+ if (error == EFAULT)
+ panic("exec: EFAULT");
}
(void) suword((caddr_t)ap, 0);
- setregs();
+
+ /*
+ * Reset caught signals. Held signals
+ * remain held through p_sigmask.
+ */
+ while (u.u_procp->p_sigcatch) {
+ nc = ffs((long)u.u_procp->p_sigcatch);
+ u.u_procp->p_sigcatch &= ~sigmask(nc);
+ u.u_signal[nc] = SIG_DFL;
+ }
+ /*
+ * Reset stack state to the user stack.
+ * Clear set of signals caught on the signal stack.
+ */
+ u.u_onstack = 0;
+ u.u_sigsp = 0;
+ u.u_sigonstack = 0;
+
+ for (nc = u.u_lastfile; nc >= 0; --nc) {
+ if (u.u_pofile[nc] & UF_EXCLOSE) {
+ closef(u.u_ofile[nc]);
+ u.u_ofile[nc] = NULL;
+ u.u_pofile[nc] = 0;
+ }
+ u.u_pofile[nc] &= ~UF_MAPPED;
+ }
+ while (u.u_lastfile >= 0 && u.u_ofile[u.u_lastfile] == NULL)
+ u.u_lastfile--;
+ setregs(exdata.ex_exec.a_entry);
+ /*
+ * Remember file name for accounting.
+ */
+ u.u_acflag &= ~AFORK;
+ if (indir)
+ bcopy((caddr_t)cfname, (caddr_t)u.u_comm, MAXCOMLEN);
+ else {
+ if (ndp->ni_dent.d_namlen > MAXCOMLEN)
+ ndp->ni_dent.d_namlen = MAXCOMLEN;
+ bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)u.u_comm,
+ (unsigned)(ndp->ni_dent.d_namlen + 1));
+ }
bad:
if (bp)
brelse(bp);
if (bno)
+#ifdef SECSIZE
+ rmfree(argmap, (clrnd((int)btoc(NCARGS))) * CLBYTES / argdbsize,
+ bno);
+#else SECSIZE
rmfree(argmap, (long)ctod(clrnd((int) btoc(NCARGS))), bno);
- iput(ip);
+#endif SECSIZE
+ if (vp)
+ vput(vp);
}
/*
* Read in and set up memory for executed file.
*/
-getxfile(ip, nargc, uid, gid)
- register struct inode *ip;
+getxfile(vp, ep, nargc, uid, gid, cred)
+ register struct vnode *vp;
+ register struct exec *ep;
int nargc, uid, gid;
+ struct ucred *cred;
{
- register size_t ts, ds, ss;
+ size_t ts, ds, ids, uds, ss;
int pagi;
- if (u.u_exdata.ux_mag == 0413)
- pagi = SPAGI;
+ if (ep->a_magic == ZMAGIC)
+ pagi = SPAGV;
else
pagi = 0;
- if (u.u_exdata.ux_tsize!=0 && (ip->i_flag&ITEXT)==0 &&
- ip->i_count!=1) {
+ if (vp->v_text && (vp->v_text->x_flag & XTRC)) {
+ u.u_error = ETXTBSY;
+ goto bad;
+ }
+ if (ep->a_text != 0 && (vp->v_flag & VTEXT) == 0 &&
+ vp->v_count != 1) {
register struct file *fp;
for (fp = file; fp < fileNFILE; fp++) {
- if (fp->f_type == DTYPE_INODE &&
+ if (fp->f_type == DTYPE_VNODE &&
fp->f_count > 0 &&
- (struct inode *)fp->f_data == ip &&
- (fp->f_flag&FWRITE)) {
+ (struct vnode *)fp->f_data == vp &&
+ (fp->f_flag & FWRITE)) {
u.u_error = ETXTBSY;
goto bad;
}
/*
* Compute text and data sizes and make sure not too large.
+ * NB - Check data and bss separately as they may overflow
+ * when summed together.
*/
- ts = clrnd(btoc(u.u_exdata.ux_tsize));
- ds = clrnd(btoc((u.u_exdata.ux_dsize+u.u_exdata.ux_bsize)));
+ ts = clrnd(btoc(ep->a_text));
+ ids = clrnd(btoc(ep->a_data));
+ uds = clrnd(btoc(ep->a_bss));
+ ds = clrnd(btoc(ep->a_data + ep->a_bss));
ss = clrnd(SSIZE + btoc(nargc));
- if (chksize((unsigned)ts, (unsigned)ds, (unsigned)ss))
+ if (chksize((unsigned)ts, (unsigned)ids, (unsigned)uds, (unsigned)ss))
goto bad;
/*
goto bad;
/*
- * At this point, committed to the new image!
+ * At this point, we are committed to the new image!
* Release virtual memory resources of old process, and
* initialize the virtual memory of the new process.
* If we resulted from vfork(), instead wakeup our
sleep((caddr_t)u.u_procp, PZERO - 1);
u.u_procp->p_flag &= ~(SVFDONE|SKEEP);
}
- u.u_procp->p_flag &= ~(SPAGI|SSEQL|SUANOM|SOUSIG);
- u.u_procp->p_flag |= pagi;
+ u.u_procp->p_flag &= ~(SPAGV|SSEQL|SUANOM|SOUSIG);
+ u.u_procp->p_flag |= pagi | SEXEC;
u.u_dmap = u.u_cdmap;
u.u_smap = u.u_csmap;
vgetvm(ts, ds, ss);
if (pagi == 0)
- u.u_error =
- rdwri(UIO_READ, ip,
+ u.u_error = vn_rdwr(UIO_READ, vp,
(char *)ctob(dptov(u.u_procp, 0)),
- (int)u.u_exdata.ux_dsize,
- (int)(sizeof(u.u_exdata)+u.u_exdata.ux_tsize),
- 0, (int *)0);
- xalloc(ip, pagi);
+ (int)ep->a_data,
+ (off_t)(sizeof (struct exec) + ep->a_text),
+ UIO_USERSPACE, (IO_UNIT|IO_NODELOCKED), cred, (int *)0);
+ xalloc(vp, ep, pagi, cred);
+#if defined(tahoe)
+ /*
+ * Define new keys.
+ */
+ if (u.u_procp->p_textp == 0) { /* use existing code key if shared */
+ ckeyrelease(u.u_procp->p_ckey);
+ u.u_procp->p_ckey = getcodekey();
+ }
+ mtpr(CCK, u.u_procp->p_ckey);
+ dkeyrelease(u.u_procp->p_dkey);
+ u.u_procp->p_dkey = getdatakey();
+ mtpr(DCK, u.u_procp->p_dkey);
+#endif
if (pagi && u.u_procp->p_textp)
vinifod((struct fpte *)dptopte(u.u_procp, 0),
- PG_FTEXT, u.u_procp->p_textp->x_iptr,
- (long)(1 + ts/CLSIZE), (int)btoc(u.u_exdata.ux_dsize));
+ PG_FTEXT, u.u_procp->p_textp->x_vptr,
+ (long)(1 + ts/CLSIZE), (size_t)btoc(ep->a_data));
-#ifdef vax
+#if defined(vax) || defined(tahoe)
/* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */
-#include "../vax/mtpr.h" /* XXX */
mtpr(TBIA, 0);
#endif
if (u.u_error)
- swkill(u.u_procp, "i/o error mapping pages");
+ swkill(u.u_procp, "exec: I/O error mapping pages");
/*
* set SUID/SGID protections, if no tracing
*/
if ((u.u_procp->p_flag&STRC)==0) {
+ if (uid != u.u_uid || gid != u.u_gid)
+ u.u_cred = crcopy(u.u_cred);
u.u_uid = uid;
u.u_procp->p_uid = uid;
u.u_gid = gid;
u.u_tsize = ts;
u.u_dsize = ds;
u.u_ssize = ss;
+ u.u_prof.pr_scale = 0;
+#if defined(tahoe)
+ u.u_pcb.pcb_savacc.faddr = (float *)NULL;
+#endif
bad:
return;
}
-
-/*
- * Clear registers on exec
- */
-setregs()
-{
- register int (**rp)();
- register int i, sigmask;
- register struct proc *p = u.u_procp;
-
- rp = &u.u_signal[1];
- for (sigmask = 1; rp < &u.u_signal[NSIG]; sigmask <<= 1, rp++)
- /* disallow masked signals to carry over? */
- if (p->p_sigcatch & sigmask && (p->p_sigmask & sigmask) == 0) {
- (void) spl6();
- p->p_sigcatch &= ~sigmask;
- *rp = SIG_DFL;
- (void) spl0();
- }
-#ifdef vax
-/*
- for (rp = &u.u_ar0[0]; rp < &u.u_ar0[16];)
- *rp++ = 0;
-*/
- u.u_ar0[PC] = u.u_exdata.ux_entloc+2;
-#endif
-#ifdef sun
- { register struct regs *r = (struct regs *)u.u_ar0;
- for (i = 0; i < 8; i++) {
- r->r_dreg[i] = 0;
- if (&r->r_areg[i] != &r->r_sp)
- r->r_areg[i] = 0;
- }
- r->r_sr = PSL_USERSET;
- r->r_pc = u.u_exdata.ux_entloc;
- }
-#endif
- for (i=0; i<NOFILE; i++) {
- if (u.u_pofile[i]&UF_EXCLOSE) {
- closef(u.u_ofile[i], u.u_pofile[i]);
- u.u_ofile[i] = NULL;
- u.u_pofile[i] = 0;
- }
- u.u_pofile[i] &= ~UF_MAPPED;
- }
-
- /*
- * Remember file name for accounting.
- */
- u.u_acflag &= ~AFORK;
- bcopy((caddr_t)u.u_dent.d_name, (caddr_t)u.u_comm,
- (unsigned)(u.u_dent.d_namlen + 1));
-#ifdef sun
- u.u_eosys = REALLYRETURN;
-#endif
-}