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 = ®loc[0]; cp < ®loc[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: }