Commit | Line | Data |
---|---|---|
da7c5cc6 | 1 | /* |
0880b18e | 2 | * Copyright (c) 1982, 1986 Regents of the University of California. |
da7c5cc6 KM |
3 | * All rights reserved. The Berkeley software License Agreement |
4 | * specifies the terms and conditions for redistribution. | |
5 | * | |
609e7cfa | 6 | * @(#)kern_exec.c 7.4 (Berkeley) %G% |
da7c5cc6 | 7 | */ |
28db9b87 SL |
8 | |
9 | #include "../machine/reg.h" | |
10 | #include "../machine/pte.h" | |
11 | #include "../machine/psl.h" | |
fb1db32c | 12 | #include "../machine/mtpr.h" |
28db9b87 | 13 | |
94368568 JB |
14 | #include "param.h" |
15 | #include "systm.h" | |
16 | #include "map.h" | |
17 | #include "dir.h" | |
18 | #include "user.h" | |
19 | #include "kernel.h" | |
20 | #include "proc.h" | |
21 | #include "buf.h" | |
22 | #include "inode.h" | |
23 | #include "seg.h" | |
24 | #include "vm.h" | |
25 | #include "text.h" | |
26 | #include "file.h" | |
27 | #include "uio.h" | |
28 | #include "acct.h" | |
29 | #include "exec.h" | |
28db9b87 SL |
30 | |
31 | /* | |
32 | * exec system call, with and without environments. | |
33 | */ | |
34 | struct execa { | |
35 | char *fname; | |
36 | char **argp; | |
37 | char **envp; | |
38 | }; | |
39 | ||
40 | execv() | |
41 | { | |
42 | ((struct execa *)u.u_ap)->envp = NULL; | |
43 | execve(); | |
44 | } | |
45 | ||
46 | execve() | |
47 | { | |
48 | register nc; | |
49 | register char *cp; | |
50 | register struct buf *bp; | |
51 | register struct execa *uap; | |
8011f5df MK |
52 | int na, ne, ucp, ap, cc; |
53 | unsigned len; | |
28db9b87 SL |
54 | int indir, uid, gid; |
55 | char *sharg; | |
56 | struct inode *ip; | |
57 | swblk_t bno; | |
58 | char cfname[MAXCOMLEN + 1]; | |
cb9392ae | 59 | char cfarg[MAXINTERP]; |
9fd50f35 | 60 | union { |
cb9392ae | 61 | char ex_shell[MAXINTERP]; /* #! and interpreter name */ |
9fd50f35 SL |
62 | struct exec ex_exec; |
63 | } exdata; | |
715baff1 | 64 | register struct nameidata *ndp = &u.u_nd; |
f3aaea26 | 65 | int resid, error; |
ec67a3ce MK |
66 | #ifdef SECSIZE |
67 | extern long argdbsize; /* XXX */ | |
68 | #endif SECSIZE | |
28db9b87 | 69 | |
715baff1 KM |
70 | ndp->ni_nameiop = LOOKUP | FOLLOW; |
71 | ndp->ni_segflg = UIO_USERSPACE; | |
72 | ndp->ni_dirp = ((struct execa *)u.u_ap)->fname; | |
73 | if ((ip = namei(ndp)) == NULL) | |
28db9b87 SL |
74 | return; |
75 | bno = 0; | |
76 | bp = 0; | |
77 | indir = 0; | |
78 | uid = u.u_uid; | |
79 | gid = u.u_gid; | |
80 | if (ip->i_mode & ISUID) | |
81 | uid = ip->i_uid; | |
82 | if (ip->i_mode & ISGID) | |
83 | gid = ip->i_gid; | |
84 | ||
85 | again: | |
86 | if (access(ip, IEXEC)) | |
87 | goto bad; | |
88 | if ((u.u_procp->p_flag&STRC) && access(ip, IREAD)) | |
89 | goto bad; | |
90 | if ((ip->i_mode & IFMT) != IFREG || | |
91 | (ip->i_mode & (IEXEC|(IEXEC>>3)|(IEXEC>>6))) == 0) { | |
92 | u.u_error = EACCES; | |
93 | goto bad; | |
94 | } | |
95 | ||
96 | /* | |
f3aaea26 | 97 | * Read in first few bytes of file for segment sizes, magic number: |
28db9b87 SL |
98 | * 407 = plain executable |
99 | * 410 = RO text | |
100 | * 413 = demand paged RO text | |
101 | * Also an ASCII line beginning with #! is | |
102 | * the file name of a ``shell'' and arguments may be prepended | |
103 | * to the argument list if given here. | |
104 | * | |
105 | * SHELL NAMES ARE LIMITED IN LENGTH. | |
106 | * | |
107 | * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM | |
108 | * THE ASCII LINE. | |
109 | */ | |
9fd50f35 | 110 | exdata.ex_shell[0] = '\0'; /* for zero length files */ |
f3aaea26 | 111 | u.u_error = rdwri(UIO_READ, ip, (caddr_t)&exdata, sizeof (exdata), |
8011f5df | 112 | (off_t)0, 1, &resid); |
28db9b87 SL |
113 | if (u.u_error) |
114 | goto bad; | |
28db9b87 | 115 | #ifndef lint |
ce66cb03 | 116 | if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) && |
9fd50f35 | 117 | exdata.ex_shell[0] != '#') { |
28db9b87 SL |
118 | u.u_error = ENOEXEC; |
119 | goto bad; | |
120 | } | |
121 | #endif | |
aec7dd3b | 122 | switch ((int)exdata.ex_exec.a_magic) { |
28db9b87 SL |
123 | |
124 | case 0407: | |
9fd50f35 SL |
125 | exdata.ex_exec.a_data += exdata.ex_exec.a_text; |
126 | exdata.ex_exec.a_text = 0; | |
28db9b87 SL |
127 | break; |
128 | ||
129 | case 0413: | |
130 | case 0410: | |
9fd50f35 | 131 | if (exdata.ex_exec.a_text == 0) { |
28db9b87 SL |
132 | u.u_error = ENOEXEC; |
133 | goto bad; | |
134 | } | |
135 | break; | |
136 | ||
137 | default: | |
9fd50f35 SL |
138 | if (exdata.ex_shell[0] != '#' || |
139 | exdata.ex_shell[1] != '!' || | |
28db9b87 SL |
140 | indir) { |
141 | u.u_error = ENOEXEC; | |
142 | goto bad; | |
143 | } | |
9fd50f35 | 144 | cp = &exdata.ex_shell[2]; /* skip "#!" */ |
cb9392ae | 145 | while (cp < &exdata.ex_shell[MAXINTERP]) { |
28db9b87 SL |
146 | if (*cp == '\t') |
147 | *cp = ' '; | |
148 | else if (*cp == '\n') { | |
149 | *cp = '\0'; | |
150 | break; | |
151 | } | |
152 | cp++; | |
153 | } | |
154 | if (*cp != '\0') { | |
155 | u.u_error = ENOEXEC; | |
156 | goto bad; | |
157 | } | |
9fd50f35 | 158 | cp = &exdata.ex_shell[2]; |
28db9b87 SL |
159 | while (*cp == ' ') |
160 | cp++; | |
715baff1 | 161 | ndp->ni_dirp = cp; |
28db9b87 SL |
162 | while (*cp && *cp != ' ') |
163 | cp++; | |
ce66cb03 | 164 | cfarg[0] = '\0'; |
28db9b87 SL |
165 | if (*cp) { |
166 | *cp++ = '\0'; | |
167 | while (*cp == ' ') | |
168 | cp++; | |
ce66cb03 | 169 | if (*cp) |
cb9392ae | 170 | bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP); |
28db9b87 | 171 | } |
28db9b87 SL |
172 | indir = 1; |
173 | iput(ip); | |
715baff1 KM |
174 | ndp->ni_nameiop = LOOKUP | FOLLOW; |
175 | ndp->ni_segflg = UIO_SYSSPACE; | |
176 | ip = namei(ndp); | |
28db9b87 SL |
177 | if (ip == NULL) |
178 | return; | |
ce66cb03 MK |
179 | bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname, |
180 | MAXCOMLEN); | |
181 | cfname[MAXCOMLEN] = '\0'; | |
28db9b87 SL |
182 | goto again; |
183 | } | |
184 | ||
185 | /* | |
186 | * Collect arguments on "file" in swap space. | |
187 | */ | |
188 | na = 0; | |
189 | ne = 0; | |
190 | nc = 0; | |
f3aaea26 | 191 | cc = 0; |
28db9b87 | 192 | uap = (struct execa *)u.u_ap; |
ec67a3ce MK |
193 | #ifdef SECSIZE |
194 | bno = rmalloc(argmap, (clrnd((int)btoc(NCARGS))) * CLBYTES / argdbsize); | |
195 | #else SECSIZE | |
9fd50f35 | 196 | bno = rmalloc(argmap, (long)ctod(clrnd((int)btoc(NCARGS)))); |
ec67a3ce | 197 | #endif SECSIZE |
9fd50f35 | 198 | if (bno == 0) { |
d03b3d84 | 199 | swkill(u.u_procp, "exec: no swap space"); |
28db9b87 SL |
200 | goto bad; |
201 | } | |
202 | if (bno % CLSIZE) | |
203 | panic("execa rmalloc"); | |
f3aaea26 SL |
204 | /* |
205 | * Copy arguments into file in argdev area. | |
206 | */ | |
28db9b87 SL |
207 | if (uap->argp) for (;;) { |
208 | ap = NULL; | |
ce66cb03 MK |
209 | sharg = NULL; |
210 | if (indir && na == 0) { | |
211 | sharg = cfname; | |
212 | ap = (int)sharg; | |
213 | uap->argp++; /* ignore argv[0] */ | |
214 | } else if (indir && (na == 1 && cfarg[0])) { | |
215 | sharg = cfarg; | |
216 | ap = (int)sharg; | |
217 | } else if (indir && (na == 1 || na == 2 && cfarg[0])) | |
28db9b87 SL |
218 | ap = (int)uap->fname; |
219 | else if (uap->argp) { | |
220 | ap = fuword((caddr_t)uap->argp); | |
221 | uap->argp++; | |
222 | } | |
f3aaea26 | 223 | if (ap == NULL && uap->envp) { |
28db9b87 | 224 | uap->argp = NULL; |
f3aaea26 SL |
225 | if ((ap = fuword((caddr_t)uap->envp)) != NULL) |
226 | uap->envp++, ne++; | |
28db9b87 SL |
227 | } |
228 | if (ap == NULL) | |
229 | break; | |
230 | na++; | |
f3aaea26 | 231 | if (ap == -1) { |
1daa95c7 | 232 | u.u_error = EFAULT; |
f3aaea26 SL |
233 | break; |
234 | } | |
28db9b87 | 235 | do { |
f3aaea26 SL |
236 | if (cc <= 0) { |
237 | /* | |
238 | * We depend on NCARGS being a multiple of | |
ec67a3ce | 239 | * CLBYTES. This way we need only check |
f3aaea26 SL |
240 | * overflow before each buffer allocation. |
241 | */ | |
242 | if (nc >= NCARGS-1) { | |
243 | error = E2BIG; | |
244 | break; | |
245 | } | |
28db9b87 SL |
246 | if (bp) |
247 | bdwrite(bp); | |
ec67a3ce MK |
248 | cc = CLBYTES; |
249 | #ifdef SECSIZE | |
250 | bp = getblk(argdev, bno + nc / argdbsize, cc, | |
251 | argdbsize); | |
252 | #else SECSIZE | |
f3aaea26 | 253 | bp = getblk(argdev, bno + ctod(nc/NBPG), cc); |
ec67a3ce | 254 | #endif SECSIZE |
28db9b87 SL |
255 | cp = bp->b_un.b_addr; |
256 | } | |
ce66cb03 | 257 | if (sharg) { |
8011f5df | 258 | error = copystr(sharg, cp, (unsigned)cc, &len); |
ce66cb03 MK |
259 | sharg += len; |
260 | } else { | |
8011f5df MK |
261 | error = copyinstr((caddr_t)ap, cp, (unsigned)cc, |
262 | &len); | |
ce66cb03 MK |
263 | ap += len; |
264 | } | |
f3aaea26 SL |
265 | cp += len; |
266 | nc += len; | |
267 | cc -= len; | |
268 | } while (error == ENOENT); | |
269 | if (error) { | |
270 | u.u_error = error; | |
271 | if (bp) | |
272 | brelse(bp); | |
273 | bp = 0; | |
274 | goto badarg; | |
275 | } | |
28db9b87 SL |
276 | } |
277 | if (bp) | |
278 | bdwrite(bp); | |
279 | bp = 0; | |
280 | nc = (nc + NBPW-1) & ~(NBPW-1); | |
9fd50f35 | 281 | getxfile(ip, &exdata.ex_exec, nc + (na+4)*NBPW, uid, gid); |
28db9b87 SL |
282 | if (u.u_error) { |
283 | badarg: | |
f3aaea26 | 284 | for (cc = 0; cc < nc; cc += CLSIZE*NBPG) { |
ec67a3ce MK |
285 | #ifdef SECSIZE |
286 | bp = baddr(argdev, bno + cc / argdbsize, CLSIZE*NBPG, | |
287 | argdbsize); | |
288 | #else SECSIZE | |
f3aaea26 | 289 | bp = baddr(argdev, bno + ctod(cc/NBPG), CLSIZE*NBPG); |
ec67a3ce | 290 | #endif SECSIZE |
28db9b87 SL |
291 | if (bp) { |
292 | bp->b_flags |= B_AGE; /* throw away */ | |
293 | bp->b_flags &= ~B_DELWRI; /* cancel io */ | |
294 | brelse(bp); | |
295 | bp = 0; | |
296 | } | |
297 | } | |
298 | goto bad; | |
299 | } | |
ce66cb03 MK |
300 | iput(ip); |
301 | ip = NULL; | |
28db9b87 SL |
302 | |
303 | /* | |
f3aaea26 | 304 | * Copy back arglist. |
28db9b87 SL |
305 | */ |
306 | ucp = USRSTACK - nc - NBPW; | |
307 | ap = ucp - na*NBPW - 3*NBPW; | |
308 | u.u_ar0[SP] = ap; | |
309 | (void) suword((caddr_t)ap, na-ne); | |
310 | nc = 0; | |
72d4f41a | 311 | cc = 0; |
28db9b87 SL |
312 | for (;;) { |
313 | ap += NBPW; | |
f3aaea26 | 314 | if (na == ne) { |
28db9b87 SL |
315 | (void) suword((caddr_t)ap, 0); |
316 | ap += NBPW; | |
317 | } | |
318 | if (--na < 0) | |
319 | break; | |
320 | (void) suword((caddr_t)ap, ucp); | |
321 | do { | |
72d4f41a | 322 | if (cc <= 0) { |
28db9b87 SL |
323 | if (bp) |
324 | brelse(bp); | |
ec67a3ce MK |
325 | cc = CLBYTES; |
326 | #ifdef SECSIZE | |
327 | bp = bread(argdev, bno + nc / argdbsize, cc, | |
328 | argdbsize); | |
329 | #else SECSIZE | |
72d4f41a | 330 | bp = bread(argdev, bno + ctod(nc / NBPG), cc); |
ec67a3ce | 331 | #endif SECSIZE |
28db9b87 SL |
332 | bp->b_flags |= B_AGE; /* throw away */ |
333 | bp->b_flags &= ~B_DELWRI; /* cancel io */ | |
334 | cp = bp->b_un.b_addr; | |
335 | } | |
8011f5df MK |
336 | error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc, |
337 | &len); | |
72d4f41a SL |
338 | ucp += len; |
339 | cp += len; | |
340 | nc += len; | |
341 | cc -= len; | |
342 | } while (error == ENOENT); | |
343 | if (error == EFAULT) | |
344 | panic("exec: EFAULT"); | |
28db9b87 SL |
345 | } |
346 | (void) suword((caddr_t)ap, 0); | |
ce66cb03 MK |
347 | |
348 | /* | |
349 | * Reset caught signals. Held signals | |
350 | * remain held through p_sigmask. | |
351 | */ | |
352 | while (u.u_procp->p_sigcatch) { | |
8011f5df | 353 | nc = ffs((long)u.u_procp->p_sigcatch); |
ce66cb03 MK |
354 | u.u_procp->p_sigcatch &= ~sigmask(nc); |
355 | u.u_signal[nc] = SIG_DFL; | |
356 | } | |
357 | /* | |
358 | * Reset stack state to the user stack. | |
359 | * Clear set of signals caught on the signal stack. | |
360 | */ | |
361 | u.u_onstack = 0; | |
362 | u.u_sigsp = 0; | |
363 | u.u_sigonstack = 0; | |
364 | ||
365 | for (nc = u.u_lastfile; nc >= 0; --nc) { | |
366 | if (u.u_pofile[nc] & UF_EXCLOSE) { | |
367 | closef(u.u_ofile[nc]); | |
368 | u.u_ofile[nc] = NULL; | |
369 | u.u_pofile[nc] = 0; | |
370 | } | |
371 | u.u_pofile[nc] &= ~UF_MAPPED; | |
372 | } | |
373 | while (u.u_lastfile >= 0 && u.u_ofile[u.u_lastfile] == NULL) | |
374 | u.u_lastfile--; | |
9fd50f35 | 375 | setregs(exdata.ex_exec.a_entry); |
715baff1 KM |
376 | /* |
377 | * Remember file name for accounting. | |
378 | */ | |
379 | u.u_acflag &= ~AFORK; | |
ce66cb03 MK |
380 | if (indir) |
381 | bcopy((caddr_t)cfname, (caddr_t)u.u_comm, MAXCOMLEN); | |
382 | else { | |
383 | if (ndp->ni_dent.d_namlen > MAXCOMLEN) | |
384 | ndp->ni_dent.d_namlen = MAXCOMLEN; | |
385 | bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)u.u_comm, | |
386 | (unsigned)(ndp->ni_dent.d_namlen + 1)); | |
387 | } | |
28db9b87 SL |
388 | bad: |
389 | if (bp) | |
390 | brelse(bp); | |
391 | if (bno) | |
ec67a3ce MK |
392 | #ifdef SECSIZE |
393 | rmfree(argmap, (clrnd((int)btoc(NCARGS))) * CLBYTES / argdbsize, | |
394 | bno); | |
395 | #else SECSIZE | |
28db9b87 | 396 | rmfree(argmap, (long)ctod(clrnd((int) btoc(NCARGS))), bno); |
ec67a3ce | 397 | #endif SECSIZE |
ce66cb03 MK |
398 | if (ip) |
399 | iput(ip); | |
28db9b87 SL |
400 | } |
401 | ||
402 | /* | |
403 | * Read in and set up memory for executed file. | |
404 | */ | |
9fd50f35 | 405 | getxfile(ip, ep, nargc, uid, gid) |
28db9b87 | 406 | register struct inode *ip; |
9fd50f35 | 407 | register struct exec *ep; |
28db9b87 SL |
408 | int nargc, uid, gid; |
409 | { | |
0c48b03e | 410 | size_t ts, ds, ids, uds, ss; |
28db9b87 SL |
411 | int pagi; |
412 | ||
9fd50f35 | 413 | if (ep->a_magic == 0413) |
28db9b87 SL |
414 | pagi = SPAGI; |
415 | else | |
416 | pagi = 0; | |
cdb14d96 | 417 | if (ip->i_text && (ip->i_text->x_flag & XTRC)) { |
ce08d752 MK |
418 | u.u_error = ETXTBSY; |
419 | goto bad; | |
420 | } | |
9fd50f35 SL |
421 | if (ep->a_text != 0 && (ip->i_flag&ITEXT) == 0 && |
422 | ip->i_count != 1) { | |
28db9b87 SL |
423 | register struct file *fp; |
424 | ||
425 | for (fp = file; fp < fileNFILE; fp++) { | |
426 | if (fp->f_type == DTYPE_INODE && | |
427 | fp->f_count > 0 && | |
428 | (struct inode *)fp->f_data == ip && | |
429 | (fp->f_flag&FWRITE)) { | |
430 | u.u_error = ETXTBSY; | |
431 | goto bad; | |
432 | } | |
433 | } | |
434 | } | |
435 | ||
436 | /* | |
437 | * Compute text and data sizes and make sure not too large. | |
0c48b03e KM |
438 | * NB - Check data and bss separately as they may overflow |
439 | * when summed together. | |
28db9b87 | 440 | */ |
9fd50f35 | 441 | ts = clrnd(btoc(ep->a_text)); |
0c48b03e KM |
442 | ids = clrnd(btoc(ep->a_data)); |
443 | uds = clrnd(btoc(ep->a_bss)); | |
f3aaea26 | 444 | ds = clrnd(btoc(ep->a_data + ep->a_bss)); |
28db9b87 | 445 | ss = clrnd(SSIZE + btoc(nargc)); |
0c48b03e | 446 | if (chksize((unsigned)ts, (unsigned)ids, (unsigned)uds, (unsigned)ss)) |
28db9b87 SL |
447 | goto bad; |
448 | ||
449 | /* | |
450 | * Make sure enough space to start process. | |
451 | */ | |
452 | u.u_cdmap = zdmap; | |
453 | u.u_csmap = zdmap; | |
454 | if (swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap) == NULL) | |
455 | goto bad; | |
456 | ||
457 | /* | |
458 | * At this point, committed to the new image! | |
459 | * Release virtual memory resources of old process, and | |
460 | * initialize the virtual memory of the new process. | |
461 | * If we resulted from vfork(), instead wakeup our | |
462 | * parent who will set SVFDONE when he has taken back | |
463 | * our resources. | |
464 | */ | |
465 | if ((u.u_procp->p_flag & SVFORK) == 0) | |
466 | vrelvm(); | |
467 | else { | |
468 | u.u_procp->p_flag &= ~SVFORK; | |
469 | u.u_procp->p_flag |= SKEEP; | |
470 | wakeup((caddr_t)u.u_procp); | |
471 | while ((u.u_procp->p_flag & SVFDONE) == 0) | |
472 | sleep((caddr_t)u.u_procp, PZERO - 1); | |
473 | u.u_procp->p_flag &= ~(SVFDONE|SKEEP); | |
474 | } | |
dd012d1e | 475 | u.u_procp->p_flag &= ~(SPAGI|SSEQL|SUANOM|SOUSIG); |
28db9b87 SL |
476 | u.u_procp->p_flag |= pagi; |
477 | u.u_dmap = u.u_cdmap; | |
478 | u.u_smap = u.u_csmap; | |
479 | vgetvm(ts, ds, ss); | |
480 | ||
481 | if (pagi == 0) | |
482 | u.u_error = | |
483 | rdwri(UIO_READ, ip, | |
484 | (char *)ctob(dptov(u.u_procp, 0)), | |
9fd50f35 | 485 | (int)ep->a_data, |
8011f5df | 486 | (off_t)(sizeof (struct exec) + ep->a_text), |
28db9b87 | 487 | 0, (int *)0); |
9fd50f35 | 488 | xalloc(ip, ep, pagi); |
fb1db32c MK |
489 | #if defined(tahoe) |
490 | /* | |
491 | * Define new keys. | |
492 | */ | |
493 | if (u.u_procp->p_textp == 0) { /* use existing code key if shared */ | |
494 | ckeyrelease(u.u_procp->p_ckey); | |
495 | u.u_procp->p_ckey = getcodekey(); | |
496 | } | |
497 | mtpr(CCK, u.u_procp->p_ckey); | |
498 | dkeyrelease(u.u_procp->p_dkey); | |
499 | u.u_procp->p_dkey = getdatakey(); | |
500 | mtpr(DCK, u.u_procp->p_dkey); | |
501 | #endif | |
28db9b87 SL |
502 | if (pagi && u.u_procp->p_textp) |
503 | vinifod((struct fpte *)dptopte(u.u_procp, 0), | |
504 | PG_FTEXT, u.u_procp->p_textp->x_iptr, | |
8011f5df | 505 | (long)(1 + ts/CLSIZE), (size_t)btoc(ep->a_data)); |
28db9b87 | 506 | |
fb1db32c | 507 | #if defined(vax) || defined(tahoe) |
28db9b87 | 508 | /* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */ |
28db9b87 SL |
509 | mtpr(TBIA, 0); |
510 | #endif | |
511 | ||
512 | if (u.u_error) | |
d03b3d84 | 513 | swkill(u.u_procp, "exec: I/O error mapping pages"); |
28db9b87 SL |
514 | /* |
515 | * set SUID/SGID protections, if no tracing | |
516 | */ | |
517 | if ((u.u_procp->p_flag&STRC)==0) { | |
518 | u.u_uid = uid; | |
519 | u.u_procp->p_uid = uid; | |
520 | u.u_gid = gid; | |
521 | } else | |
522 | psignal(u.u_procp, SIGTRAP); | |
523 | u.u_tsize = ts; | |
524 | u.u_dsize = ds; | |
525 | u.u_ssize = ss; | |
d4a03a57 | 526 | u.u_prof.pr_scale = 0; |
fb1db32c MK |
527 | #if defined(tahoe) |
528 | u.u_pcb.pcb_savacc.faddr = (float *)NULL; | |
529 | #endif | |
28db9b87 SL |
530 | bad: |
531 | return; | |
532 | } |