RETURN => return, remove syscontext.h
[unix-history] / usr / src / sys / kern / kern_exec.c
CommitLineData
da7c5cc6 1/*
c4ec2128
KM
2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3 * All rights reserved.
da7c5cc6 4 *
c4ec2128
KM
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 *
d9c2f47f 17 * @(#)kern_exec.c 7.28 (Berkeley) %G%
da7c5cc6 18 */
28db9b87 19
94368568
JB
20#include "param.h"
21#include "systm.h"
22#include "map.h"
d9c2f47f 23#include "user.h"
94368568
JB
24#include "kernel.h"
25#include "proc.h"
c4ec2128
KM
26#include "mount.h"
27#include "ucred.h"
28#include "malloc.h"
94368568 29#include "buf.h"
c4ec2128 30#include "vnode.h"
94368568
JB
31#include "seg.h"
32#include "vm.h"
33#include "text.h"
34#include "file.h"
35#include "uio.h"
36#include "acct.h"
37#include "exec.h"
28db9b87 38
d301d150
KM
39#include "machine/reg.h"
40#include "machine/pte.h"
41#include "machine/psl.h"
42#include "machine/mtpr.h"
43
93422d4b
KM
44#ifdef HPUXCOMPAT
45#include "../hpux/hpux_exec.h"
46#endif
47
28db9b87
SL
48/*
49 * exec system call, with and without environments.
50 */
c9714ae3
KM
51execv(p, uap, retval)
52 struct proc *p;
53 struct args {
54 char *fname;
55 char **argp;
56 char **envp;
57 } *uap;
58 int *retval;
28db9b87 59{
c9714ae3
KM
60
61 uap->envp = NULL;
d9c2f47f 62 return (execve(p, uap, retval));
28db9b87
SL
63}
64
c9714ae3
KM
65/* ARGSUSED */
66execve(p, uap, retval)
67 register struct proc *p;
68 register struct args {
69 char *fname;
70 char **argp;
71 char **envp;
72 } *uap;
73 int *retval;
28db9b87
SL
74{
75 register nc;
76 register char *cp;
77 register struct buf *bp;
c4ec2128 78 struct buf *tbp;
8011f5df
MK
79 int na, ne, ucp, ap, cc;
80 unsigned len;
28db9b87
SL
81 int indir, uid, gid;
82 char *sharg;
c4ec2128 83 struct vnode *vp;
28db9b87 84 swblk_t bno;
c4ec2128 85 struct vattr vattr;
28db9b87 86 char cfname[MAXCOMLEN + 1];
cb9392ae 87 char cfarg[MAXINTERP];
9fd50f35 88 union {
cb9392ae 89 char ex_shell[MAXINTERP]; /* #! and interpreter name */
9fd50f35 90 struct exec ex_exec;
93422d4b
KM
91#ifdef HPUXCOMPAT
92 struct hpux_exec ex_hexec;
93#endif
9fd50f35 94 } exdata;
93422d4b
KM
95#ifdef HPUXCOMPAT
96 struct hpux_exec hhead;
97#endif
c9714ae3 98 register struct ucred *cred = u.u_cred;
715baff1 99 register struct nameidata *ndp = &u.u_nd;
93422d4b 100 int resid, error, flags = 0;
ec67a3ce
MK
101#ifdef SECSIZE
102 extern long argdbsize; /* XXX */
103#endif SECSIZE
28db9b87 104
ba32f7c0 105 start:
c4ec2128 106 ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
715baff1 107 ndp->ni_segflg = UIO_USERSPACE;
c9714ae3
KM
108 ndp->ni_dirp = uap->fname;
109 if (error = namei(ndp))
d9c2f47f 110 return (error);
c4ec2128 111 vp = ndp->ni_vp;
28db9b87
SL
112 bno = 0;
113 bp = 0;
114 indir = 0;
c9714ae3
KM
115 uid = cred->cr_uid;
116 gid = cred->cr_gid;
117 if (error = VOP_GETATTR(vp, &vattr, cred))
c4ec2128 118 goto bad;
54fb9dc2 119 if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
c9714ae3 120 error = EACCES;
c4ec2128
KM
121 goto bad;
122 }
54fb9dc2 123 if ((vp->v_mount->mnt_flag & MNT_NOSUID) == 0) {
c4ec2128
KM
124 if (vattr.va_mode & VSUID)
125 uid = vattr.va_uid;
126 if (vattr.va_mode & VSGID)
127 gid = vattr.va_gid;
128 }
28db9b87
SL
129
130 again:
c9714ae3 131 if (error = VOP_ACCESS(vp, VEXEC, cred))
28db9b87 132 goto bad;
c9714ae3 133 if ((p->p_flag & STRC) && (error = VOP_ACCESS(vp, VREAD, cred)))
28db9b87 134 goto bad;
c4ec2128
KM
135 if (vp->v_type != VREG ||
136 (vattr.va_mode & (VEXEC|(VEXEC>>3)|(VEXEC>>6))) == 0) {
c9714ae3 137 error = EACCES;
28db9b87
SL
138 goto bad;
139 }
140
141 /*
f3aaea26 142 * Read in first few bytes of file for segment sizes, magic number:
c4ec2128
KM
143 * OMAGIC = plain executable
144 * NMAGIC = RO text
145 * ZMAGIC = demand paged RO text
28db9b87
SL
146 * Also an ASCII line beginning with #! is
147 * the file name of a ``shell'' and arguments may be prepended
148 * to the argument list if given here.
149 *
150 * SHELL NAMES ARE LIMITED IN LENGTH.
151 *
152 * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM
153 * THE ASCII LINE.
154 */
9fd50f35 155 exdata.ex_shell[0] = '\0'; /* for zero length files */
c9714ae3
KM
156 error = vn_rdwr(UIO_READ, vp, (caddr_t)&exdata, sizeof (exdata),
157 (off_t)0, UIO_SYSSPACE, (IO_UNIT|IO_NODELOCKED), cred, &resid);
158 if (error)
28db9b87 159 goto bad;
28db9b87 160#ifndef lint
ce66cb03 161 if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) &&
9fd50f35 162 exdata.ex_shell[0] != '#') {
c9714ae3 163 error = ENOEXEC;
28db9b87
SL
164 goto bad;
165 }
93422d4b
KM
166#endif
167#if defined(hp300)
168 switch ((int)exdata.ex_exec.a_mid) {
169
170 /*
171 * An ancient hp200 or hp300 binary, shouldn't happen anymore.
172 * Mark as invalid.
173 */
174 case MID_ZERO:
175 exdata.ex_exec.a_magic = 0;
176 break;
177
178 /*
179 * HP200 series has a smaller page size so we cannot
180 * demand-load or even write protect text, so we just
181 * treat as OMAGIC.
182 */
183 case MID_HP200:
184 exdata.ex_exec.a_magic = OMAGIC;
185 break;
186
187 case MID_HP300:
188 break;
189
190#ifdef HPUXCOMPAT
191 case MID_HPUX:
192 /*
193 * Save a.out header. This is eventually saved in the pcb,
194 * but we cannot do that yet in case the exec fails before
195 * the image is overlayed.
196 */
197 bcopy((caddr_t)&exdata.ex_hexec,
198 (caddr_t)&hhead, sizeof hhead);
199 /*
200 * If version number is 0x2bad this is a native BSD
201 * binary created via the HPUX SGS. Should not be
202 * treated as an HPUX binary.
203 */
204 if (exdata.ex_hexec.ha_version != BSDVNUM)
205 flags |= SHPUX;
206 /*
207 * Shuffle important fields to their BSD locations.
208 * Note that the order in which this is done is important.
209 */
210 exdata.ex_exec.a_text = exdata.ex_hexec.ha_text;
211 exdata.ex_exec.a_data = exdata.ex_hexec.ha_data;
212 exdata.ex_exec.a_bss = exdata.ex_hexec.ha_bss;
213 exdata.ex_exec.a_entry = exdata.ex_hexec.ha_entry;
214 /*
215 * For ZMAGIC files, make sizes consistant with those
216 * generated by BSD ld.
217 */
218 if (exdata.ex_exec.a_magic == ZMAGIC) {
219 exdata.ex_exec.a_text =
220 ctob(btoc(exdata.ex_exec.a_text));
221 nc = exdata.ex_exec.a_data + exdata.ex_exec.a_bss;
222 exdata.ex_exec.a_data =
223 ctob(btoc(exdata.ex_exec.a_data));
224 nc -= (int)exdata.ex_exec.a_data;
225 exdata.ex_exec.a_bss = (nc < 0) ? 0 : nc;
226 }
227 break;
228#endif
229 }
28db9b87 230#endif
aec7dd3b 231 switch ((int)exdata.ex_exec.a_magic) {
28db9b87 232
c4ec2128 233 case OMAGIC:
9fd50f35
SL
234 exdata.ex_exec.a_data += exdata.ex_exec.a_text;
235 exdata.ex_exec.a_text = 0;
28db9b87
SL
236 break;
237
c4ec2128 238 case ZMAGIC:
93422d4b 239 flags |= SPAGV;
c4ec2128 240 case NMAGIC:
9fd50f35 241 if (exdata.ex_exec.a_text == 0) {
c9714ae3 242 error = ENOEXEC;
28db9b87
SL
243 goto bad;
244 }
245 break;
246
247 default:
446115cb
MK
248 if (exdata.ex_shell[0] != '#' ||
249 exdata.ex_shell[1] != '!' ||
250 indir) {
c9714ae3 251 error = ENOEXEC;
28db9b87
SL
252 goto bad;
253 }
d26813a4 254 for (cp = &exdata.ex_shell[2];; ++cp) {
446115cb 255 if (cp >= &exdata.ex_shell[MAXINTERP]) {
c9714ae3 256 error = ENOEXEC;
d26813a4
KB
257 goto bad;
258 }
259 if (*cp == '\n') {
28db9b87
SL
260 *cp = '\0';
261 break;
262 }
d26813a4
KB
263 if (*cp == '\t')
264 *cp = ' ';
28db9b87 265 }
446115cb
MK
266 cp = &exdata.ex_shell[2];
267 while (*cp == ' ')
268 cp++;
715baff1 269 ndp->ni_dirp = cp;
446115cb
MK
270 while (*cp && *cp != ' ')
271 cp++;
e7db1101 272 cfarg[0] = '\0';
28db9b87 273 if (*cp) {
446115cb
MK
274 *cp++ = '\0';
275 while (*cp == ' ')
276 cp++;
ce66cb03 277 if (*cp)
cb9392ae 278 bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP);
e7db1101 279 }
446115cb 280 indir = 1;
c4ec2128
KM
281 vput(vp);
282 ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
715baff1 283 ndp->ni_segflg = UIO_SYSSPACE;
c9714ae3 284 if (error = namei(ndp))
d9c2f47f 285 return (error);
c4ec2128 286 vp = ndp->ni_vp;
c9714ae3 287 if (error = VOP_GETATTR(vp, &vattr, cred))
c4ec2128 288 goto bad;
ce66cb03
MK
289 bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname,
290 MAXCOMLEN);
291 cfname[MAXCOMLEN] = '\0';
c9714ae3
KM
292 uid = cred->cr_uid; /* shell scripts can't be setuid */
293 gid = cred->cr_gid;
28db9b87
SL
294 goto again;
295 }
ba32f7c0
KM
296 /*
297 * If the vnode has been modified since we last used it,
298 * then throw away all its pages and its text table entry.
299 */
300 if (vp->v_text && vp->v_text->x_mtime != vattr.va_mtime.tv_sec) {
301 /*
302 * Try once to release, if it is still busy
303 * take more drastic action.
304 */
305 xrele(vp);
306 if (vp->v_flag & VTEXT) {
307 vput(vp);
308 vgone(vp);
309 goto start;
310 }
311 }
28db9b87
SL
312
313 /*
314 * Collect arguments on "file" in swap space.
315 */
316 na = 0;
317 ne = 0;
318 nc = 0;
f3aaea26 319 cc = 0;
ec67a3ce
MK
320#ifdef SECSIZE
321 bno = rmalloc(argmap, (clrnd((int)btoc(NCARGS))) * CLBYTES / argdbsize);
322#else SECSIZE
9fd50f35 323 bno = rmalloc(argmap, (long)ctod(clrnd((int)btoc(NCARGS))));
ec67a3ce 324#endif SECSIZE
9fd50f35 325 if (bno == 0) {
c9714ae3 326 swkill(p, "exec: no swap space");
28db9b87
SL
327 goto bad;
328 }
329 if (bno % CLSIZE)
330 panic("execa rmalloc");
93422d4b
KM
331#ifdef GENERIC
332 if (rootdev == dumpdev)
333 bno += 4096;
334#endif
f3aaea26
SL
335 /*
336 * Copy arguments into file in argdev area.
337 */
28db9b87
SL
338 if (uap->argp) for (;;) {
339 ap = NULL;
ce66cb03
MK
340 sharg = NULL;
341 if (indir && na == 0) {
342 sharg = cfname;
343 ap = (int)sharg;
344 uap->argp++; /* ignore argv[0] */
345 } else if (indir && (na == 1 && cfarg[0])) {
346 sharg = cfarg;
347 ap = (int)sharg;
348 } else if (indir && (na == 1 || na == 2 && cfarg[0]))
28db9b87
SL
349 ap = (int)uap->fname;
350 else if (uap->argp) {
351 ap = fuword((caddr_t)uap->argp);
352 uap->argp++;
353 }
f3aaea26 354 if (ap == NULL && uap->envp) {
28db9b87 355 uap->argp = NULL;
f3aaea26
SL
356 if ((ap = fuword((caddr_t)uap->envp)) != NULL)
357 uap->envp++, ne++;
28db9b87
SL
358 }
359 if (ap == NULL)
360 break;
361 na++;
f3aaea26 362 if (ap == -1) {
c9714ae3 363 error = EFAULT;
93422d4b
KM
364 if (bp) {
365 brelse(bp);
366 bp = 0;
367 }
368 goto badarg;
f3aaea26 369 }
28db9b87 370 do {
f3aaea26
SL
371 if (cc <= 0) {
372 /*
373 * We depend on NCARGS being a multiple of
ec67a3ce 374 * CLBYTES. This way we need only check
f3aaea26
SL
375 * overflow before each buffer allocation.
376 */
377 if (nc >= NCARGS-1) {
378 error = E2BIG;
379 break;
380 }
28db9b87
SL
381 if (bp)
382 bdwrite(bp);
ec67a3ce
MK
383 cc = CLBYTES;
384#ifdef SECSIZE
385 bp = getblk(argdev, bno + nc / argdbsize, cc,
386 argdbsize);
387#else SECSIZE
c4ec2128 388 bp = getblk(argdev_vp, bno + ctod(nc/NBPG), cc);
ec67a3ce 389#endif SECSIZE
28db9b87
SL
390 cp = bp->b_un.b_addr;
391 }
ce66cb03 392 if (sharg) {
8011f5df 393 error = copystr(sharg, cp, (unsigned)cc, &len);
ce66cb03
MK
394 sharg += len;
395 } else {
8011f5df
MK
396 error = copyinstr((caddr_t)ap, cp, (unsigned)cc,
397 &len);
ce66cb03
MK
398 ap += len;
399 }
f3aaea26
SL
400 cp += len;
401 nc += len;
402 cc -= len;
403 } while (error == ENOENT);
404 if (error) {
f3aaea26
SL
405 if (bp)
406 brelse(bp);
407 bp = 0;
408 goto badarg;
409 }
28db9b87
SL
410 }
411 if (bp)
412 bdwrite(bp);
413 bp = 0;
414 nc = (nc + NBPW-1) & ~(NBPW-1);
c9714ae3
KM
415 error = getxfile(p, vp, &exdata.ex_exec, flags, nc + (na+4)*NBPW,
416 uid, gid);
417 if (error) {
28db9b87 418badarg:
c4ec2128 419 for (cc = 0; cc < nc; cc += CLBYTES) {
2fd88d7d 420 (void) baddr(argdev_vp, bno + ctod(cc/NBPG),
9ad9d3f8 421 CLBYTES, NOCRED, &tbp);
c4ec2128 422 bp = tbp;
ec67a3ce 423#endif SECSIZE
28db9b87 424 if (bp) {
a4292a03 425 bp->b_flags |= B_INVAL; /* throw away */
28db9b87
SL
426 brelse(bp);
427 bp = 0;
428 }
429 }
430 goto bad;
431 }
33f18f0f
MH
432 if (vp->v_text)
433 vp->v_text->x_mtime = vattr.va_mtime.tv_sec;
c4ec2128
KM
434 vput(vp);
435 vp = NULL;
28db9b87 436
93422d4b
KM
437#ifdef HPUXCOMPAT
438 /*
439 * We are now committed to the exec so we can save the exec
440 * header in the pcb where we can dump it if necessary in core()
441 */
442 if (u.u_pcb.pcb_flags & PCB_HPUXBIN)
443 bcopy((caddr_t)&hhead,
444 (caddr_t)u.u_pcb.pcb_exec, sizeof hhead);
445#endif
446
28db9b87 447 /*
f3aaea26 448 * Copy back arglist.
28db9b87
SL
449 */
450 ucp = USRSTACK - nc - NBPW;
451 ap = ucp - na*NBPW - 3*NBPW;
452 u.u_ar0[SP] = ap;
453 (void) suword((caddr_t)ap, na-ne);
454 nc = 0;
72d4f41a 455 cc = 0;
28db9b87
SL
456 for (;;) {
457 ap += NBPW;
f3aaea26 458 if (na == ne) {
28db9b87
SL
459 (void) suword((caddr_t)ap, 0);
460 ap += NBPW;
461 }
462 if (--na < 0)
463 break;
464 (void) suword((caddr_t)ap, ucp);
465 do {
72d4f41a 466 if (cc <= 0) {
28db9b87
SL
467 if (bp)
468 brelse(bp);
ec67a3ce
MK
469 cc = CLBYTES;
470#ifdef SECSIZE
471 bp = bread(argdev, bno + nc / argdbsize, cc,
472 argdbsize);
473#else SECSIZE
c4ec2128 474 error = bread(argdev_vp,
9ad9d3f8
KM
475 (daddr_t)(bno + ctod(nc / NBPG)), cc,
476 NOCRED, &tbp);
c4ec2128 477 bp = tbp;
ec67a3ce 478#endif SECSIZE
a4292a03 479 bp->b_flags |= B_INVAL; /* throw away */
28db9b87
SL
480 cp = bp->b_un.b_addr;
481 }
8011f5df
MK
482 error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc,
483 &len);
72d4f41a
SL
484 ucp += len;
485 cp += len;
486 nc += len;
487 cc -= len;
488 } while (error == ENOENT);
489 if (error == EFAULT)
490 panic("exec: EFAULT");
28db9b87
SL
491 }
492 (void) suword((caddr_t)ap, 0);
ce66cb03 493
c9714ae3 494 execsigs(p);
ce66cb03
MK
495
496 for (nc = u.u_lastfile; nc >= 0; --nc) {
497 if (u.u_pofile[nc] & UF_EXCLOSE) {
69be5b7a 498 (void) closef(u.u_ofile[nc]);
ce66cb03
MK
499 u.u_ofile[nc] = NULL;
500 u.u_pofile[nc] = 0;
501 }
502 u.u_pofile[nc] &= ~UF_MAPPED;
503 }
504 while (u.u_lastfile >= 0 && u.u_ofile[u.u_lastfile] == NULL)
505 u.u_lastfile--;
ddb266b6 506 setregs(exdata.ex_exec.a_entry, retval);
715baff1
KM
507 /*
508 * Remember file name for accounting.
509 */
510 u.u_acflag &= ~AFORK;
ce66cb03 511 if (indir)
c9714ae3 512 bcopy((caddr_t)cfname, (caddr_t)p->p_comm, MAXCOMLEN);
ce66cb03
MK
513 else {
514 if (ndp->ni_dent.d_namlen > MAXCOMLEN)
515 ndp->ni_dent.d_namlen = MAXCOMLEN;
c9714ae3 516 bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)p->p_comm,
ce66cb03
MK
517 (unsigned)(ndp->ni_dent.d_namlen + 1));
518 }
28db9b87
SL
519bad:
520 if (bp)
521 brelse(bp);
522 if (bno)
ec67a3ce
MK
523#ifdef SECSIZE
524 rmfree(argmap, (clrnd((int)btoc(NCARGS))) * CLBYTES / argdbsize,
525 bno);
526#else SECSIZE
28db9b87 527 rmfree(argmap, (long)ctod(clrnd((int) btoc(NCARGS))), bno);
ec67a3ce 528#endif SECSIZE
c4ec2128
KM
529 if (vp)
530 vput(vp);
d9c2f47f 531 return (error);
28db9b87
SL
532}
533
534/*
535 * Read in and set up memory for executed file.
536 */
c9714ae3
KM
537getxfile(p, vp, ep, flags, nargc, uid, gid)
538 register struct proc *p;
c4ec2128 539 register struct vnode *vp;
9fd50f35 540 register struct exec *ep;
93422d4b 541 int flags, nargc, uid, gid;
28db9b87 542{
e5b27ef1 543 segsz_t ts, ds, ids, uds, ss;
c9714ae3 544 register struct ucred *cred = u.u_cred;
93422d4b 545 off_t toff;
c9714ae3 546 int error;
28db9b87 547
93422d4b
KM
548#ifdef HPUXCOMPAT
549 if (ep->a_mid == MID_HPUX)
550 toff = sizeof (struct hpux_exec);
28db9b87 551 else
93422d4b
KM
552#endif
553 toff = sizeof (struct exec);
c9714ae3
KM
554 if (vp->v_text && (vp->v_text->x_flag & XTRC))
555 return (ETXTBSY);
c4ec2128 556 if (ep->a_text != 0 && (vp->v_flag & VTEXT) == 0 &&
c65056fe 557 vp->v_usecount != 1) {
28db9b87
SL
558 register struct file *fp;
559
560 for (fp = file; fp < fileNFILE; fp++) {
c4ec2128 561 if (fp->f_type == DTYPE_VNODE &&
28db9b87 562 fp->f_count > 0 &&
c4ec2128
KM
563 (struct vnode *)fp->f_data == vp &&
564 (fp->f_flag & FWRITE)) {
c9714ae3 565 return (ETXTBSY);
28db9b87
SL
566 }
567 }
568 }
569
570 /*
571 * Compute text and data sizes and make sure not too large.
0c48b03e
KM
572 * NB - Check data and bss separately as they may overflow
573 * when summed together.
28db9b87 574 */
9fd50f35 575 ts = clrnd(btoc(ep->a_text));
0c48b03e
KM
576 ids = clrnd(btoc(ep->a_data));
577 uds = clrnd(btoc(ep->a_bss));
f3aaea26 578 ds = clrnd(btoc(ep->a_data + ep->a_bss));
28db9b87 579 ss = clrnd(SSIZE + btoc(nargc));
c9714ae3
KM
580 if (error =
581 chksize((unsigned)ts, (unsigned)ids, (unsigned)uds, (unsigned)ss))
582 return (error);
28db9b87
SL
583
584 /*
585 * Make sure enough space to start process.
586 */
587 u.u_cdmap = zdmap;
588 u.u_csmap = zdmap;
c9714ae3
KM
589 if (error = swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap))
590 return (error);
28db9b87
SL
591
592 /*
c4ec2128 593 * At this point, we are committed to the new image!
28db9b87
SL
594 * Release virtual memory resources of old process, and
595 * initialize the virtual memory of the new process.
596 * If we resulted from vfork(), instead wakeup our
597 * parent who will set SVFDONE when he has taken back
598 * our resources.
599 */
93422d4b
KM
600 if ((p->p_flag & SVFORK) == 0) {
601#ifdef MAPMEM
c9714ae3
KM
602 if (u.u_mmap && (error = mmexec(p)))
603 return (error);
93422d4b 604#endif
28db9b87 605 vrelvm();
93422d4b 606 } else {
ba7abd07
MK
607 p->p_flag &= ~SVFORK;
608 p->p_flag |= SKEEP;
609 wakeup((caddr_t)p);
610 while ((p->p_flag & SVFDONE) == 0)
611 sleep((caddr_t)p, PZERO - 1);
612 p->p_flag &= ~(SVFDONE|SKEEP);
28db9b87 613 }
93422d4b
KM
614#ifdef hp300
615 u.u_pcb.pcb_flags &= ~(PCB_AST|PCB_HPUXMMAP|PCB_HPUXBIN);
616#ifdef HPUXCOMPAT
617 /* remember that we were loaded from an HPUX format file */
618 if (ep->a_mid == MID_HPUX)
619 u.u_pcb.pcb_flags |= PCB_HPUXBIN;
620#endif
621#endif
622 p->p_flag &= ~(SPAGV|SSEQL|SUANOM|SHPUX);
623 p->p_flag |= flags | SEXEC;
28db9b87
SL
624 u.u_dmap = u.u_cdmap;
625 u.u_smap = u.u_csmap;
626 vgetvm(ts, ds, ss);
627
93422d4b 628 if ((flags & SPAGV) == 0)
c9714ae3 629 (void) vn_rdwr(UIO_READ, vp,
93422d4b 630 (char *)ctob(dptov(p, 0)),
9fd50f35 631 (int)ep->a_data,
93422d4b 632 (off_t)(toff + ep->a_text),
c4ec2128 633 UIO_USERSPACE, (IO_UNIT|IO_NODELOCKED), cred, (int *)0);
93422d4b 634 xalloc(vp, ep, toff, cred);
fb1db32c
MK
635#if defined(tahoe)
636 /*
637 * Define new keys.
638 */
ba7abd07
MK
639 if (p->p_textp == 0) { /* use existing code key if shared */
640 ckeyrelease(p->p_ckey);
641 p->p_ckey = getcodekey();
fb1db32c 642 }
ba7abd07
MK
643 mtpr(CCK, p->p_ckey);
644 dkeyrelease(p->p_dkey);
645 p->p_dkey = getdatakey();
646 mtpr(DCK, p->p_dkey);
fb1db32c 647#endif
93422d4b
KM
648 if ((flags & SPAGV) && p->p_textp)
649 vinifod(p, (struct fpte *)dptopte(p, 0),
ba7abd07 650 PG_FTEXT, p->p_textp->x_vptr,
e5b27ef1 651 (long)(1 + ts/CLSIZE), (segsz_t)btoc(ep->a_data));
28db9b87 652
fb1db32c 653#if defined(vax) || defined(tahoe)
28db9b87 654 /* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */
28db9b87
SL
655 mtpr(TBIA, 0);
656#endif
93422d4b
KM
657#ifdef hp300
658 TBIAU();
659#endif
28db9b87 660
28db9b87
SL
661 /*
662 * set SUID/SGID protections, if no tracing
663 */
ba7abd07 664 if ((p->p_flag&STRC)==0) {
c9714ae3
KM
665 if (uid != cred->cr_uid || gid != cred->cr_gid)
666 u.u_cred = cred = crcopy(cred);
667 cred->cr_uid = uid;
668 cred->cr_gid = gid;
ba7abd07 669 p->p_uid = uid;
28db9b87 670 } else
ba7abd07
MK
671 psignal(p, SIGTRAP);
672 p->p_svuid = p->p_uid;
c9714ae3 673 p->p_svgid = cred->cr_gid;
28db9b87
SL
674 u.u_tsize = ts;
675 u.u_dsize = ds;
676 u.u_ssize = ss;
d4a03a57 677 u.u_prof.pr_scale = 0;
fb1db32c
MK
678#if defined(tahoe)
679 u.u_pcb.pcb_savacc.faddr = (float *)NULL;
680#endif
c9714ae3 681 return (0);
28db9b87 682}