1: #
   2: /*
   3:  */
   4: 
   5: #include "../param.h"
   6: #include "../systm.h"
   7: #include "../user.h"
   8: #include "../proc.h"
   9: #include "../buf.h"
  10: #include "../reg.h"
  11: #include "../inode.h"
  12: 
  13: /*
  14:  * exec system call.
  15:  * Because of the fact that an I/O buffer is used
  16:  * to store the caller's arguments during exec,
  17:  * and more buffers are needed to read in the text file,
  18:  * deadly embraces waiting for free buffers are possible.
  19:  * Therefore the number of processes simultaneously
  20:  * running in exec has to be limited to NEXEC.
  21:  */
  22: #define EXPRI   -1
  23: 
  24: exec()
  25: {
  26:     int ap, na, nc, *bp;
  27:     int ts, ds, sep;
  28:     register c, *ip;
  29:     register char *cp;
  30:     extern uchar;
  31: 
  32:     /*
  33: 	 * pick up file names
  34: 	 * and check various modes
  35: 	 * for execute permission
  36: 	 */
  37: 
  38:     ip = namei(&uchar, 0);
  39:     if(ip == NULL)
  40:         return;
  41:     while(execnt >= NEXEC)
  42:         sleep(&execnt, EXPRI);
  43:     execnt++;
  44:     bp = getblk(NODEV);
  45:     if(access(ip, IEXEC) || (ip->i_mode&IFMT)!=0)
  46:         goto bad;
  47: 
  48:     /*
  49: 	 * pack up arguments into
  50: 	 * allocated disk buffer
  51: 	 */
  52: 
  53:     cp = bp->b_addr;
  54:     na = 0;
  55:     nc = 0;
  56:     while(ap = fuword(u.u_arg[1])) {
  57:         na++;
  58:         if(ap == -1)
  59:             goto bad;
  60:         u.u_arg[1] =+ 2;
  61:         for(;;) {
  62:             c = fubyte(ap++);
  63:             if(c == -1)
  64:                 goto bad;
  65:             *cp++ = c;
  66:             nc++;
  67:             if(nc > 510) {
  68:                 u.u_error = E2BIG;
  69:                 goto bad;
  70:             }
  71:             if(c == 0)
  72:                 break;
  73:         }
  74:     }
  75:     if((nc&1) != 0) {
  76:         *cp++ = 0;
  77:         nc++;
  78:     }
  79: 
  80:     /*
  81: 	 * read in first 8 bytes
  82: 	 * of file for segment
  83: 	 * sizes:
  84: 	 * w0 = 407/410/411 (410 implies RO text) (411 implies sep ID)
  85: 	 * w1 = text size
  86: 	 * w2 = data size
  87: 	 * w3 = bss size
  88: 	 */
  89: 
  90:     u.u_base = &u.u_arg[0];
  91:     u.u_count = 8;
  92:     u.u_offset[1] = 0;
  93:     u.u_offset[0] = 0;
  94:     u.u_segflg = 1;
  95:     readi(ip);
  96:     u.u_segflg = 0;
  97:     if(u.u_error)
  98:         goto bad;
  99:     sep = 0;
 100:     if(u.u_arg[0] == 0407) {
 101:         u.u_arg[2] =+ u.u_arg[1];
 102:         u.u_arg[1] = 0;
 103:     } else
 104:     if(u.u_arg[0] == 0411)
 105:         sep++; else
 106:     if(u.u_arg[0] != 0410) {
 107:         u.u_error = ENOEXEC;
 108:         goto bad;
 109:     }
 110:     if(u.u_arg[1]!=0 && (ip->i_flag&ITEXT)==0 && ip->i_count!=1) {
 111:         u.u_error = ETXTBSY;
 112:         goto bad;
 113:     }
 114: 
 115:     /*
 116: 	 * find text and data sizes
 117: 	 * try them out for possible
 118: 	 * exceed of max sizes
 119: 	 */
 120: 
 121:     ts = ((u.u_arg[1]+63)>>6) & 01777;
 122:     ds = ((u.u_arg[2]+u.u_arg[3]+63)>>6) & 01777;
 123:     if(estabur(ts, ds, SSIZE, sep))
 124:         goto bad;
 125: 
 126:     /*
 127: 	 * allocate and clear core
 128: 	 * at this point, committed
 129: 	 * to the new image
 130: 	 */
 131: 
 132:     u.u_prof[3] = 0;
 133:     xfree();
 134:     expand(USIZE);
 135:     xalloc(ip);
 136:     c = USIZE+ds+SSIZE;
 137:     expand(c);
 138:     while(--c >= USIZE)
 139:         clearseg(u.u_procp->p_addr+c);
 140: 
 141:     /*
 142: 	 * read in data segment
 143: 	 */
 144: 
 145:     estabur(0, ds, 0, 0);
 146:     u.u_base = 0;
 147:     u.u_offset[1] = 020+u.u_arg[1];
 148:     u.u_count = u.u_arg[2];
 149:     readi(ip);
 150: 
 151:     /*
 152: 	 * initialize stack segment
 153: 	 */
 154: 
 155:     u.u_tsize = ts;
 156:     u.u_dsize = ds;
 157:     u.u_ssize = SSIZE;
 158:     u.u_sep = sep;
 159:     estabur(u.u_tsize, u.u_dsize, u.u_ssize, u.u_sep);
 160:     cp = bp->b_addr;
 161:     ap = -nc - na*2 - 4;
 162:     u.u_ar0[R6] = ap;
 163:     suword(ap, na);
 164:     c = -nc;
 165:     while(na--) {
 166:         suword(ap=+2, c);
 167:         do
 168:             subyte(c++, *cp);
 169:         while(*cp++);
 170:     }
 171:     suword(ap+2, -1);
 172: 
 173:     /*
 174: 	 * set SUID/SGID protections, if no tracing
 175: 	 */
 176: 
 177:     if ((u.u_procp->p_flag&STRC)==0) {
 178:         if(ip->i_mode&ISUID)
 179:             if(u.u_uid != 0) {
 180:                 u.u_uid = ip->i_uid;
 181:                 u.u_procp->p_uid = ip->i_uid;
 182:             }
 183:         if(ip->i_mode&ISGID)
 184:             u.u_gid = ip->i_gid;
 185:     }
 186: 
 187:     /*
 188: 	 * clear sigs, regs and return
 189: 	 */
 190: 
 191:     c = ip;
 192:     for(ip = &u.u_signal[0]; ip < &u.u_signal[NSIG]; ip++)
 193:         if((*ip & 1) == 0)
 194:             *ip = 0;
 195:     for(cp = &regloc[0]; cp < &regloc[6];)
 196:         u.u_ar0[*cp++] = 0;
 197:     u.u_ar0[R7] = 0;
 198:     for(ip = &u.u_fsav[0]; ip < &u.u_fsav[25];)
 199:         *ip++ = 0;
 200:     ip = c;
 201: 
 202: bad:
 203:     iput(ip);
 204:     brelse(bp);
 205:     if(execnt >= NEXEC)
 206:         wakeup(&execnt);
 207:     execnt--;
 208: }
 209: 
 210: /*
 211:  * exit system call:
 212:  * pass back caller's r0
 213:  */
 214: rexit()
 215: {
 216: 
 217:     u.u_arg[0] = u.u_ar0[R0] << 8;
 218:     exit();
 219: }
 220: 
 221: /*
 222:  * Release resources.
 223:  * Save u. area for parent to look at.
 224:  * Enter zombie state.
 225:  * Wake up parent and init processes,
 226:  * and dispose of children.
 227:  */
 228: exit()
 229: {
 230:     register int *q, a;
 231:     register struct proc *p;
 232: 
 233:     u.u_procp->p_flag =& ~STRC;
 234:     for(q = &u.u_signal[0]; q < &u.u_signal[NSIG];)
 235:         *q++ = 1;
 236:     for(q = &u.u_ofile[0]; q < &u.u_ofile[NOFILE]; q++)
 237:         if(a = *q) {
 238:             *q = NULL;
 239:             closef(a);
 240:         }
 241:     iput(u.u_cdir);
 242:     xfree();
 243:     a = malloc(swapmap, 1);
 244:     if(a == NULL)
 245:         panic("out of swap");
 246:     p = getblk(swapdev, a);
 247:     bcopy(&u, p->b_addr, 256);
 248:     bwrite(p);
 249:     q = u.u_procp;
 250:     mfree(coremap, q->p_size, q->p_addr);
 251:     q->p_addr = a;
 252:     q->p_stat = SZOMB;
 253: 
 254: loop:
 255:     for(p = &proc[0]; p < &proc[NPROC]; p++)
 256:     if(q->p_ppid == p->p_pid) {
 257:         wakeup(&proc[1]);
 258:         wakeup(p);
 259:         for(p = &proc[0]; p < &proc[NPROC]; p++)
 260:         if(q->p_pid == p->p_ppid) {
 261:             p->p_ppid  = 1;
 262:             if (p->p_stat == SSTOP)
 263:                 setrun(p);
 264:         }
 265:         swtch();
 266:         /* no return */
 267:     }
 268:     q->p_ppid = 1;
 269:     goto loop;
 270: }
 271: 
 272: /*
 273:  * Wait system call.
 274:  * Search for a terminated (zombie) child,
 275:  * finally lay it to rest, and collect its status.
 276:  * Look also for stopped (traced) children,
 277:  * and pass back status from them.
 278:  */
 279: wait()
 280: {
 281:     register f, *bp;
 282:     register struct proc *p;
 283: 
 284:     f = 0;
 285: 
 286: loop:
 287:     for(p = &proc[0]; p < &proc[NPROC]; p++)
 288:     if(p->p_ppid == u.u_procp->p_pid) {
 289:         f++;
 290:         if(p->p_stat == SZOMB) {
 291:             u.u_ar0[R0] = p->p_pid;
 292:             bp = bread(swapdev, f=p->p_addr);
 293:             mfree(swapmap, 1, f);
 294:             p->p_stat = NULL;
 295:             p->p_pid = 0;
 296:             p->p_ppid = 0;
 297:             p->p_sig = 0;
 298:             p->p_ttyp = 0;
 299:             p->p_flag = 0;
 300:             p = bp->b_addr;
 301:             u.u_cstime[0] =+ p->u_cstime[0];
 302:             dpadd(u.u_cstime, p->u_cstime[1]);
 303:             dpadd(u.u_cstime, p->u_stime);
 304:             u.u_cutime[0] =+ p->u_cutime[0];
 305:             dpadd(u.u_cutime, p->u_cutime[1]);
 306:             dpadd(u.u_cutime, p->u_utime);
 307:             u.u_ar0[R1] = p->u_arg[0];
 308:             brelse(bp);
 309:             return;
 310:         }
 311:         if(p->p_stat == SSTOP) {
 312:             if((p->p_flag&SWTED) == 0) {
 313:                 p->p_flag =| SWTED;
 314:                 u.u_ar0[R0] = p->p_pid;
 315:                 u.u_ar0[R1] = (p->p_sig<<8) | 0177;
 316:                 return;
 317:             }
 318:             p->p_flag =& ~(STRC|SWTED);
 319:             setrun(p);
 320:         }
 321:     }
 322:     if(f) {
 323:         sleep(u.u_procp, PWAIT);
 324:         goto loop;
 325:     }
 326:     u.u_error = ECHILD;
 327: }
 328: 
 329: /*
 330:  * fork system call.
 331:  */
 332: fork()
 333: {
 334:     register struct proc *p1, *p2;
 335: 
 336:     p1 = u.u_procp;
 337:     for(p2 = &proc[0]; p2 < &proc[NPROC]; p2++)
 338:         if(p2->p_stat == NULL)
 339:             goto found;
 340:     u.u_error = EAGAIN;
 341:     goto out;
 342: 
 343: found:
 344:     if(newproc()) {
 345:         u.u_ar0[R0] = p1->p_pid;
 346:         u.u_cstime[0] = 0;
 347:         u.u_cstime[1] = 0;
 348:         u.u_stime = 0;
 349:         u.u_cutime[0] = 0;
 350:         u.u_cutime[1] = 0;
 351:         u.u_utime = 0;
 352:         return;
 353:     }
 354:     u.u_ar0[R0] = p2->p_pid;
 355: 
 356: out:
 357:     u.u_ar0[R7] =+ 2;
 358: }
 359: 
 360: /*
 361:  * break system call.
 362:  *  -- bad planning: "break" is a dirty word in C.
 363:  */
 364: sbreak()
 365: {
 366:     register a, n, d;
 367:     int i;
 368: 
 369:     /*
 370: 	 * set n to new data size
 371: 	 * set d to new-old
 372: 	 * set n to new total size
 373: 	 */
 374: 
 375:     n = (((u.u_arg[0]+63)>>6) & 01777);
 376:     if(!u.u_sep)
 377:         n =- nseg(u.u_tsize) * 128;
 378:     if(n < 0)
 379:         n = 0;
 380:     d = n - u.u_dsize;
 381:     n =+ USIZE+u.u_ssize;
 382:     if(estabur(u.u_tsize, u.u_dsize+d, u.u_ssize, u.u_sep))
 383:         return;
 384:     u.u_dsize =+ d;
 385:     if(d > 0)
 386:         goto bigger;
 387:     a = u.u_procp->p_addr + n - u.u_ssize;
 388:     i = n;
 389:     n = u.u_ssize;
 390:     while(n--) {
 391:         copyseg(a-d, a);
 392:         a++;
 393:     }
 394:     expand(i);
 395:     return;
 396: 
 397: bigger:
 398:     expand(n);
 399:     a = u.u_procp->p_addr + n;
 400:     n = u.u_ssize;
 401:     while(n--) {
 402:         a--;
 403:         copyseg(a-d, a);
 404:     }
 405:     while(d--)
 406:         clearseg(--a);
 407: }

Defined functions

exec defined in line 24; never used
exit defined in line 228; used 4 times
fork defined in line 332; never used
rexit defined in line 214; never used
sbreak defined in line 364; never used
wait defined in line 279; never used

Defined macros

EXPRI defined in line 22; used 1 times
  • in line 42
Last modified: 1975-07-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1353
Valid CSS Valid XHTML 1.0 Strict