|
|
1.1 root 1: #include "sys/param.h"
2: #include "sys/systm.h"
3: #include "sys/map.h"
4: #include "sys/mtpr.h"
5: #include "sys/user.h"
6: #include "sys/proc.h"
7: #include "sys/buf.h"
8: #include "sys/reg.h"
9: #include "sys/inode.h"
10: #include "sys/acct.h"
11: #include "/usr/include/wait.h"
12: #include "sys/pte.h"
13: #include "sys/vm.h"
14: #include "sys/text.h"
15: #include "sys/psl.h"
16: #include "sys/vlimit.h"
17: #include "sys/file.h"
18:
19: /*
20: * exec system call
21: */
22: struct execa {
23: char *fname;
24: char **argp;
25: char **envp;
26: };
27:
28: struct shdata {
29: char sd_save[DIRSIZ];
30: int sd_gid;
31: int sd_uid;
32: int sd_indir;
33: char sd_flag[SHSIZE];
34: };
35:
36: struct swargs {
37: char *sw_cp;
38: int sw_argc;
39: int sw_envc;
40: int sw_chars;
41: int sw_bn;
42: struct buf *sw_bp;
43: };
44:
45: void
46: str_stash(s, sp)
47: register char *s;
48: register struct swargs *sp;
49: {
50: register char *cp;
51: register int nc;
52: register int bmask;
53:
54: cp = sp->sw_cp;
55: nc = sp->sw_chars;
56: bmask = BMASK(argdev);
57:
58: do {
59: if ((nc & bmask) == 0) {
60: if (nc >= NCARGS) {
61: u.u_error = E2BIG;
62: return;
63: }
64: if (sp->sw_bp != NULL)
65: bdwrite(sp->sw_bp);
66: sp->sw_bp = getblk(argdev, (daddr_t)(dbtofsb(argdev,
67: sp->sw_bn) + (nc>>BSHIFT(argdev))));
68: cp = sp->sw_bp->b_un.b_addr;
69: }
70: nc++;
71: } while ((*cp++ = *s++) != '\0');
72:
73: sp->sw_chars = nc;
74: sp->sw_cp = cp;
75: sp->sw_argc++;
76: }
77:
78: int
79: vec_stash(v, sp)
80: register char **v;
81: register struct swargs *sp;
82: {
83: register char *s;
84: register int nc;
85: register int nleft;
86: register int i;
87: int bsize;
88: int count;
89: int ap;
90:
91: if (v == NULL)
92: return 0;
93:
94: nc = sp->sw_chars;
95: bsize = BSIZE(argdev);
96: nleft = ((nc + bsize-1) & ~(bsize-1)) - nc;
97: count = 0;
98:
99: for (;;) {
100: if ((ap = fuword((caddr_t)v++)) < 0) {
101: u.u_error = EFAULT;
102: return 0;
103: }
104: if ((s = (char *)ap) == NULL)
105: break;
106: if ((i = fustrlen(s)) < 0) {
107: u.u_error = EFAULT;
108: return 0;
109: }
110: while (i > nleft) {
111: if (sp->sw_bp) {
112: bcopy(s, sp->sw_cp, nleft);
113: s += nleft;
114: nc += nleft;
115: i -= nleft;
116: if (nc >= NCARGS) {
117: u.u_error = E2BIG;
118: return 0;
119: }
120: bdwrite(sp->sw_bp);
121: }
122: sp->sw_bp = getblk(argdev, (daddr_t)(dbtofsb(argdev,
123: sp->sw_bn) + (nc>>BSHIFT(argdev))));
124: sp->sw_cp = sp->sw_bp->b_un.b_addr;
125: nleft = bsize;
126: }
127: bcopy(s, sp->sw_cp, i);
128: sp->sw_cp += i;
129: nc += i;
130: nleft -= i;
131: count++;
132: }
133: sp->sw_chars = nc;
134: sp->sw_argc += count;
135: return count;
136: }
137:
138: exece()
139: {
140: register int i;
141: register int ap;
142: register int bsize;
143: register char *cp;
144: register char *ucp;
145: register struct execa *uap;
146: struct buf *bp;
147: struct inode *ip;
148: struct shdata sh;
149: struct swargs sw;
150: extern struct map argmap[];
151: extern struct inode *gethead();
152:
153: uap = (struct execa *)u.u_ap;
154: sh.sd_uid = u.u_uid;
155: sh.sd_gid = u.u_gid;
156: sh.sd_indir = 0;
157: sh.sd_flag[0] = '\0';
158: if ((ip = gethead(uap->fname, &sh)) == NULL)
159: return;
160:
161: sw.sw_argc = 0;
162: sw.sw_chars = 0;
163: sw.sw_bp = NULL;
164: bsize = BSIZE(argdev);
165: if ((sw.sw_bn = rmalloc(argmap, ctod(clrnd((int)btoc(NCARGS))))) == 0) {
166: swkill(u.u_procp, "exece");
167: iput(ip);
168: return;
169: }
170: if (sw.sw_bn % CLSIZE)
171: panic("exece rmalloc");
172: if (sh.sd_indir) {
173: if ((ap = fuword((caddr_t)uap->argp)) < 0){
174: u.u_error = EFAULT;
175: goto out;
176: }
177: if (ap) {
178: uap->argp++;
179: if (fustrlen((char *)ap) < 0) {
180: u.u_error = EFAULT;
181: goto out;
182: }
183: /*
184: * improper assumption
185: * ap is a user address;
186: * str_stash assumes kernel-accessible
187: */
188: str_stash((char *)ap, &sw);
189: }
190: if (sh.sd_flag[0] != '\0')
191: str_stash(sh.sd_flag, &sw);
192: str_stash(uap->fname, &sw);
193: }
194: vec_stash(uap->argp, &sw);
195: sw.sw_envc = vec_stash(uap->envp, &sw);
196: bp = sw.sw_bp;
197: if (bp) {
198: bdwrite(bp);
199: bp = NULL;
200: }
201:
202: if (u.u_error)
203: goto out;
204:
205: sw.sw_chars = (sw.sw_chars + NBPW-1) & ~(NBPW-1);
206: /* 4: argc, null after args, null after env, null after everything, */
207: getxfile(ip, sw.sw_chars + (sw.sw_argc+4)*NBPW, sh.sd_uid, sh.sd_gid);
208:
209: if (u.u_error)
210: goto out;
211:
212: iput(ip);
213: ucp = (char *)(USRSTACK - sw.sw_chars - NBPW);
214: ap = (int)ucp - (sw.sw_argc + 3) * NBPW;
215: u.u_ar0[SP] = ap;
216: *(int *)ap = sw.sw_argc - sw.sw_envc;
217:
218: for (i = 0, cp = ucp; sw.sw_chars > 0; i++, cp += bsize, sw.sw_chars -= bsize) {
219: if (bp)
220: brelse(bp);
221: bp = bread(argdev, (daddr_t)(dbtofsb(argdev, sw.sw_bn)+i));
222: bcopy(bp->b_un.b_addr, cp, min(bsize, sw.sw_chars));
223: bp->b_flags |= B_AGE;
224: bp->b_flags &= ~B_DELWRI;
225: }
226:
227: if (bp)
228: brelse(bp);
229:
230: for (cp = ucp; ; cp += fustrlen(cp)) {
231: ap += NBPW;
232: if (sw.sw_argc == sw.sw_envc)
233: ap += NBPW;
234: if (--sw.sw_argc < 0)
235: break;
236: *(char **)ap = cp;
237: }
238: setregs(sh.sd_save);
239: rmfree(argmap, ctod(clrnd((int) btoc(NCARGS))), sw.sw_bn);
240: return;
241:
242: out:
243: iput(ip);
244: for (i = (((sw.sw_chars+bsize-1)&~(bsize-1))>>BSHIFT(argdev))-1;
245: i >= 0; i--) {
246: bp = getblk(argdev, (daddr_t)(dbtofsb(argdev, sw.sw_bn)+i));
247: bp->b_flags |= B_AGE;
248: bp->b_flags &= ~B_DELWRI;
249: brelse(bp);
250: }
251: rmfree(argmap, ctod(clrnd((int) btoc(NCARGS))), sw.sw_bn);
252: }
253:
254: /*
255: * Get a shell after #! magic number.
256: */
257: struct inode *
258: getshell(ip, sp)
259: struct inode *ip;
260: struct shdata *sp;
261: {
262: register char *cp, *fname;
263: extern struct inode *gethead();
264:
265: if(u.u_exdata.ux_shell[0] != '#' || u.u_exdata.ux_shell[1] != '!' || sp->sd_indir)
266: goto error;
267: cp = &u.u_exdata.ux_shell[2];
268: for (;;) {
269: if (cp == &u.u_exdata.ux_shell[SHSIZE])
270: goto error;
271: if (*cp == '\n') {
272: *cp = '\0';
273: break;
274: }
275: if (*cp == '\t')
276: *cp = ' ';
277: cp++;
278: }
279: for (cp = &u.u_exdata.ux_shell[2]; *cp == ' '; cp++);
280: if (*cp == '\0')
281: goto error;
282: fname = cp;
283: while (*cp != '\0') {
284: if (*cp == ' ') {
285: *cp++ = '\0';
286: while (*cp == ' ')
287: cp++;
288: /*
289: * Shell argument (one only).
290: */
291: if (*cp != '\0') {
292: register int i;
293:
294: i = 0;
295: do
296: sp->sd_flag[i++] = *cp++;
297: while (*cp != ' ' && *cp != '\0');
298: sp->sd_flag[i] = '\0';
299: }
300: break;
301: }
302: else
303: cp++;
304: }
305: iput(ip);
306: sp->sd_indir = 1;
307: return gethead(fname, sp);
308:
309: error:
310: iput(ip);
311: u.u_error = ENOEXEC;
312: return NULL;
313: }
314:
315: /*
316: * Get the header of an executable and do all the right tests.
317: */
318: struct inode *
319: gethead(fname, sp)
320: char *fname;
321: struct shdata *sp;
322: {
323: register struct inode *ip;
324: struct argnamei nmarg;
325:
326: nmarg = nilargnamei;
327: if(sp->sd_indir == 0) {
328: nmarg.un.buf = (caddr_t)sp->sd_save;
329: nmarg.len = sizeof(sp->sd_save);
330: if((ip = namei(fname, SEGUDATA, &nmarg, 1)) == NULL)
331: return NULL;
332: }
333: else if((ip = namei(fname, SEGSYS, &nmarg, 1)) == NULL)
334: return NULL;
335:
336: /*
337: * Setuid and setgid denied for network root.
338: */
339: if (!(ip->i_mode & ICONC)) {
340: if ((ip->i_mode & ISUID) != 0 && ip->i_uid != -1)
341: sp->sd_uid = ip->i_uid;
342:
343: if ((ip->i_mode & ISGID) != 0 && ip->i_gid != -1)
344: sp->sd_gid = ip->i_gid;
345: }
346:
347: /*
348: * Check permission. May not trace something we can't read.
349: */
350: if(access(ip, IEXEC) || (PTRACED(u.u_procp) && access(ip, IREAD)))
351: goto out;
352:
353: /*
354: * Must be a regular file and must really be executable.
355: */
356: if ((ip->i_mode & IFMT) != IFREG ||
357: (ip->i_mode & (IEXEC | (IEXEC >> 3) | (IEXEC >> 6))) == 0) {
358: u.u_error = EACCES;
359: goto out;
360: }
361:
362: /*
363: * ux_mag = 407/410/413
364: * 407 is plain executable
365: * 410 is RO text
366: * 413 is demand paged RO text
367: *
368: * Also an ASCII line beginning with #! is
369: * the file name of a ``shell'' and arguments may be prepended
370: * to the argument list if given here.
371: *
372: * Shell names are limited in length.
373: *
374: * Only one argument may be passed to the shell from the ASCII line.
375: */
376: u.u_base = (caddr_t)&u.u_exdata;
377: u.u_count = sizeof(u.u_exdata);
378: u.u_offset = ltoL(0);
379: u.u_segflg = SEGSYS;
380: readi(ip);
381: u.u_segflg = SEGUDATA;
382:
383: if (u.u_error)
384: goto out;
385:
386: if (u.u_count > sizeof (u.u_exdata) - sizeof (u.u_exdata.Ux_A))
387: ip = getshell(ip, sp);
388: else {
389: switch (u.u_exdata.ux_mag) {
390: case 0407:
391: u.u_exdata.ux_dsize += u.u_exdata.ux_tsize;
392: u.u_exdata.ux_tsize = 0;
393: break;
394:
395: case 0410:
396: case 0413:
397: if (u.u_exdata.ux_tsize == 0)
398: u.u_error = ENOEXEC;
399: break;
400:
401: default:
402: ip = getshell(ip, sp);
403: }
404: }
405:
406: out:
407: if (u.u_error && ip != NULL) {
408: iput(ip);
409: ip = NULL;
410: }
411:
412: return ip;
413: }
414:
415: /*
416: * Read in and set up memory for executed file.
417: */
418: getxfile(ip, nargc, uid, gid)
419: register struct inode *ip;
420: {
421: register clicks_t ts, ds, ss;
422: int pagi;
423:
424: /* for now, no paging off alternate file systems */
425: if (u.u_exdata.ux_mag == 0413 && !BITFS(ip->i_dev) && !ip->i_fstyp)
426: pagi = SPAGI;
427: else
428: pagi = 0;
429: /* never demand-page if process is traced (panic pagein mfind) */
430: if (PTRACED(u.u_procp))
431: pagi = 0;
432:
433: if(u.u_exdata.ux_tsize!=0 && (ip->i_flag&ITEXT)==0 && ip->i_count!=1) {
434: register struct file *fp;
435:
436: for (fp = file; fp < fileNFILE; fp++)
437: if (fp->f_count && fp->f_inode==ip
438: && (fp->f_flag&FWRITE)) {
439: u.u_error = ETXTBSY;
440: goto bad;
441: }
442: }
443:
444: /*
445: * find text and data sizes
446: * try them out for possible
447: * exceed of max sizes
448: */
449:
450: ts = clrnd(btoc(u.u_exdata.ux_tsize));
451: ds = clrnd(btoc((u.u_exdata.ux_dsize+u.u_exdata.ux_bsize)));
452: ss = clrnd(SSIZE + btoc(nargc));
453: if (chksize(ts, ds, ss))
454: goto bad;
455: u.u_cdmap = zdmap;
456: u.u_csmap = zdmap;
457: if (swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap) == NULL)
458: goto bad;
459:
460: /*
461: * At this point, committed to the new image!
462: * Release virtual memory resources of old process, and
463: * initialize the virtual memory of the new process.
464: */
465: u.u_prof.pr_scale = 0;
466: vrelvm();
467: u.u_procp->p_flag &= ~(SPAGI|SSEQL|SUANOM);
468: u.u_procp->p_flag |= pagi;
469: u.u_dmap = u.u_cdmap;
470: u.u_smap = u.u_csmap;
471: vgetvm(ts, ds, ss);
472:
473: if (pagi == 0) {
474: /*
475: * Read in data segment.
476: */
477: u.u_base = (char *)ctob(ts);
478: if(u.u_exdata.ux_mag != 0413)
479: u.u_offset = ltoL(sizeof(u.u_exdata)+u.u_exdata.ux_tsize);
480: else /* stupid 1k 0413 files */
481: u.u_offset = ltoL(BSIZE(0) + u.u_exdata.ux_tsize);
482: u.u_count = u.u_exdata.ux_dsize;
483: readi(ip);
484: }
485: xalloc(ip, pagi);
486: if (pagi && u.u_procp->p_textp)
487: vinifod((struct fpte *)dptopte(u.u_procp, 0),
488: u.u_procp->p_textp->x_iptr,
489: 1 + ts/CLSIZE, (int)btoc(u.u_exdata.ux_dsize));
490:
491: /* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */
492: mtpr(TBIA, 0);
493:
494: /*
495: * set SUID/SGID protections, if no tracing
496: */
497: if (!PTRACED(u.u_procp)) {
498: u.u_uid = uid;
499: u.u_procp->p_uid = uid;
500: u.u_gid = gid;
501: }
502: if (u.u_procp->p_flag&SSEXEC)
503: psignal(u.u_procp, SIGSTOP);
504: u.u_tsize = ts;
505: u.u_dsize = ds;
506: u.u_ssize = ss;
507: bad:
508: return;
509: }
510:
511: /*
512: * Reset context on exec
513: */
514: setregs(comm)
515: char *comm;
516: {
517: register i;
518: register int (*f)();
519:
520: for (i = 0; i < NSIG; i++) {
521: if ((f = u.u_signal[i]) == SIG_DFL
522: || f == SIG_IGN || f == SIG_HOLD)
523: continue;
524: spl6(); /* needed? */
525: u.u_signal[i] = SIG_DFL;
526: P_SETDFL(u.u_procp, SIGMASK(i));
527: spl0();
528: }
529: /*
530: for(rp = &u.u_ar0[0]; rp < &u.u_ar0[16];)
531: *rp++ = 0;
532: */
533: u.u_ar0[PC] = u.u_exdata.ux_entloc + 2; /* skip over entry mask */
534: for(i=0; i<NOFILE; i++) {
535: if (u.u_pofile[i]&EXCLOSE) {
536: closef(u.u_ofile[i]);
537: u.u_ofile[i] = NULL;
538: u.u_pofile[i] &= ~EXCLOSE;
539: }
540: }
541: /*
542: * Remember file name for accounting.
543: */
544: u.u_acflag &= ~AFORK;
545: bcopy((caddr_t)comm, (caddr_t)u.u_comm, sizeof(u.u_comm));
546: }
547:
548: /*
549: * exit system call:
550: * pass back caller's arg
551: */
552: rexit()
553: {
554: register struct a {
555: int rval;
556: } *uap;
557:
558: uap = (struct a *)u.u_ap;
559: exit((uap->rval & 0377) << 8);
560: }
561:
562: /*
563: * Release resources.
564: * Save u. area for parent to look at.
565: * Enter zombie state.
566: * Wake up parent and init processes,
567: * and dispose of children.
568: */
569: exit(rv)
570: {
571: register int i;
572: register struct proc *p, *q;
573: register struct file *f;
574:
575: vmsizmon();
576: p = u.u_procp;
577: p->p_flag &= ~(STRC|SULOCK);
578: p->p_flag |= SWEXIT;
579: p->p_clktim = 0;
580: (void) spl6();
581: p->p_siga0 = p->p_siga1 = 0;
582: p->p_ignsig = ~0; /* magic: ignore all */
583: (void) spl0();
584: p->p_cpticks = 0;
585: p->p_pctcpu = 0;
586: for(i=0; i<NSIG; i++)
587: u.u_signal[i] = SIG_IGN;
588: vrelvm();
589: for(i=0; i<NOFILE; i++) {
590: if ((f = u.u_ofile[i]) == NULL)
591: continue;
592: u.u_ofile[i] = NULL;
593: closef(f);
594: }
595: plock(u.u_cdir);
596: iput(u.u_cdir);
597: if (u.u_rdir) {
598: plock(u.u_rdir);
599: iput(u.u_rdir);
600: }
601: u.u_limit[LIM_FSIZE] = INFINITY;
602: acct();
603: vrelpt(u.u_procp);
604: vrelu(u.u_procp, 0);
605: p->p_stat = SZOMB;
606: noproc = 1;
607: if (p->p_pid < SYSPIDS)
608: printf("process %d died\n", p->p_pid);
609: done:
610: ((struct xproc *)p)->xp_xstat = rv; /* overlay */
611: ((struct xproc *)p)->xp_vm = u.u_vm; /* overlay */
612: vmsadd(&((struct xproc *)p)->xp_vm, &u.u_cvm);
613: for(q = proc; q < procNPROC; q++)
614: if (q->p_stat != 0 && q->p_pptr == p) {
615: q->p_pptr = &proc[INITPID];
616: q->p_ppid = 1;
617: wakeup((caddr_t)&proc[INITPID]);
618: /*
619: * Traced processes are killed
620: * since their existence means someone is screwing up.
621: * this is probably wrong now
622: * Stopped processes are sent a hangup and a continue.
623: * This is designed to be ``safe'' for setuid
624: * processes since they must be willing to tolerate
625: * hangups anyways.
626: */
627: if (q->p_flag&STRC) {
628: q->p_flag &= ~STRC;
629: psignal(q, SIGKILL);
630: } else if (q->p_stat == SSTOP) {
631: psignal(q, SIGHUP);
632: psignal(q, SIGCONT);
633: }
634: (void) spgrp(q, -1);
635: }
636: wakeup((caddr_t)p->p_pptr);
637: if (p->p_trace)
638: wakeup((caddr_t)p->p_trace);
639: psignal(p->p_pptr, SIGCHLD);
640: swtch();
641: }
642:
643: wait()
644: {
645: struct vtimes vm;
646: struct vtimes *vp;
647:
648: if ((u.u_ar0[PS] & PSL_ALLCC) != PSL_ALLCC) {
649: wait1(0, (struct vtimes *)0);
650: return;
651: }
652: vp = (struct vtimes *)u.u_ar0[R1];
653: wait1(u.u_ar0[R0], &vm);
654: if (u.u_error)
655: return;
656: (void) copyout((caddr_t)&vm, (caddr_t)vp, sizeof (struct vtimes));
657: }
658:
659: /*
660: * Wait system call.
661: * Search for a terminated (zombie) child,
662: * finally lay it to rest, and collect its status.
663: * Look also for stopped (traced) children,
664: * and pass back status from them.
665: */
666: wait1(options, vp)
667: register options;
668: struct vtimes *vp;
669: {
670: register f;
671: register struct proc *p;
672: register struct proc *myp; /* optimization */
673:
674: f = 0;
675: myp = u.u_procp;
676: loop:
677: for(p = proc; p < procNPROC; p++) {
678: if (p->p_stat == 0 || p->p_pptr != myp)
679: continue;
680: f++;
681: if(p->p_stat == SZOMB) {
682: u.u_r.r_val1 = p->p_pid;
683: u.u_r.r_val2 = ((struct xproc *)p)->xp_xstat;
684: if (vp)
685: *vp = ((struct xproc *)p)->xp_vm;
686: vmsadd(&u.u_cvm, &((struct xproc *)p)->xp_vm);
687: p->p_stat = 0;
688: /* if it mattered, we could bzero(p, sizeof(*p)) here */
689: if (p == procNPROC - 1) {
690: do
691: --p;
692: while (p->p_stat == 0);
693: procNPROC = p + 1;
694: }
695: return;
696: }
697: if (p->p_stat == SSTOP && (p->p_flag&SWTED)==0 &&
698: (p->p_flag&STRC)==0) {
699: p->p_flag |= SWTED;
700: u.u_r.r_val1 = p->p_pid;
701: u.u_r.r_val2 = (p->p_cursig<<8) | WSTOPPED;
702: return;
703: }
704: }
705: if (f==0) {
706: u.u_error = ECHILD;
707: return;
708: }
709: if (options&WNOHANG) {
710: u.u_r.r_val1 = 0;
711: return;
712: }
713: sleep((caddr_t)myp, PWAIT);
714: goto loop;
715: }
716:
717: /*
718: * fork system call.
719: */
720: fork()
721: {
722: register struct proc *p1, *p2;
723: register int a, pid;
724: static int mpid = 0;
725:
726: u.u_cdmap = zdmap;
727: u.u_csmap = zdmap;
728: if (swpexpand(u.u_dsize, u.u_ssize, &u.u_cdmap, &u.u_csmap) == 0)
729: goto out;
730: retry:
731: pid = ++mpid;
732: if (pid > MAXPID)
733: pid = mpid = 1;
734: a = 0;
735: p2 = NULL;
736: for(p1 = proc; p1 < procNPROC; p1++) {
737: if (p1->p_stat == 0) {
738: if (p2 == NULL)
739: p2 = p1;
740: continue;
741: }
742: if (p1->p_pid == pid || p1->p_pgrp == pid)
743: goto retry;
744: if (p1->p_uid == u.u_uid)
745: a++;
746: }
747: if (p2 == NULL) { /* try pushing up high water mark */
748: for (; p1 < &proc[proccnt]; p1++)
749: if (p1->p_stat == 0) {
750: p2 = p1;
751: p1++;
752: break;
753: }
754: procNPROC = p1;
755: }
756: /*
757: * Disallow if
758: * No processes at all;
759: * not su and too many procs owned; or
760: * not su and would take last slot.
761: */
762: if (p2==NULL)
763: tablefull("proc");
764: if (p2==NULL || (u.u_uid!=0 && (p2==&proc[proccnt-1] || a>MAXUPRC))) {
765: u.u_error = EAGAIN;
766: (void) vsexpand(0, &u.u_cdmap, 1);
767: (void) vsexpand(0, &u.u_csmap, 1);
768: goto out;
769: }
770: p1 = u.u_procp;
771: if(newproc(p2, pid)) {
772: u.u_r.r_val1 = p1->p_pid;
773: u.u_r.r_val2 = 1; /* child */
774: u.u_start = time;
775: u.u_acflag = AFORK;
776: u.u_nbadio = 0;
777: return;
778: }
779: u.u_r.r_val1 = pid;
780: out:
781: u.u_r.r_val2 = 0;
782: }
783:
784: /*
785: * break system call.
786: * -- bad planning: "break" is a dirty word in C.
787: */
788: sbreak()
789: {
790: struct a {
791: char *nsiz;
792: };
793: register int n, d;
794:
795: /*
796: * set n to new data size
797: * set d to new-old
798: */
799:
800: n = btoc(((struct a *)u.u_ap)->nsiz);
801: #if NOTDEF
802: if (!u.u_sep)
803: #endif
804: n -= ctos(u.u_tsize) * stoc(1);
805: if (n < 0)
806: n = 0;
807: d = clrnd(n - u.u_dsize);
808: if (ctob(u.u_dsize+d) > u.u_limit[LIM_DATA]) {
809: u.u_error = ENOMEM;
810: return;
811: }
812: if (chksize(u.u_tsize, u.u_dsize+d, u.u_ssize))
813: return;
814: if (swpexpand(u.u_dsize+d, u.u_ssize, &u.u_dmap, &u.u_smap)==0)
815: return;
816: expand(d, P0BR);
817: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.