3000: # 3001: #include "../param.h" 3002: #include "../systm.h" 3003: #include "../user.h" 3004: #include "../proc.h" 3005: #include "../buf.h" 3006: #include "../reg.h" 3007: #include "../inode.h" 3008: 3009: /* 3010: * exec system call. 3011: * Because of the fact that an I/O buffer is used 3012: * to store the caller's arguments during exec, 3013: * and more buffers are needed to read in the text file, 3014: * deadly embraces waiting for free buffers are possible. 3015: * Therefore the number of processes simultaneously 3016: * running in exec has to be limited to NEXEC. 3017: */ 3018: #define EXPRI -1 3019: 3020: exec() 3021: { 3022: int ap, na, nc, *bp; 3023: int ts, ds, sep; 3024: register c, *ip; 3025: register char *cp; 3026: extern uchar; 3027: 3028: /* 3029: * pick up file names 3030: * and check various modes 3031: * for execute permission 3032: */ 3033: 3034: ip = namei(&uchar, 0); 3035: if(ip == NULL) 3036: return; 3037: while(execnt >= NEXEC) 3038: sleep(&execnt, EXPRI); 3039: execnt++; 3040: bp = getblk(NODEV); 3041: if(access(ip, IEXEC) || (ip->i_mode&IFMT)!=0) 3042: goto bad; 3043: 3044: /* 3045: * pack up arguments into 3046: * allocated disk buffer 3047: */ 3048: 3049: cp = bp->b_addr; 3050: na = 0; 3051: nc = 0; 3052: while(ap = fuword(u.u_arg[1])) { 3053: na++; 3054: if(ap == -1) 3055: goto bad; 3056: u.u_arg[1] =+ 2; 3057: for(;;) { 3058: c = fubyte(ap++); 3059: if(c == -1) 3060: goto bad; 3061: *cp++ = c; 3062: nc++; 3063: if(nc > 510) { 3064: u.u_error = E2BIG; 3065: goto bad; 3066: } 3067: if(c == 0) 3068: break; 3069: } 3070: } 3071: if((nc&1) != 0) { 3072: *cp++ = 0; 3073: nc++; 3074: } 3075: 3076: /* read in first 8 bytes 3077: * of file for segment 3078: * sizes: 3079: * w0 = 407/410/411 (410 implies RO text) (411 implies sep ID) 3080: * w1 = text size 3081: * w2 = data size 3082: * w3 = bss size 3083: */ 3084: 3085: u.u_base = &u.u_arg[0]; 3086: u.u_count = 8; 3087: u.u_offset[1] = 0; 3088: u.u_offset[0] = 0; 3089: u.u_segflg = 1; 3090: readi(ip); 3091: u.u_segflg = 0; 3092: if(u.u_error) 3093: goto bad; 3094: sep = 0; 3095: if(u.u_arg[0] == 0407) { 3096: u.u_arg[2] =+ u.u_arg[1]; 3097: u.u_arg[1] = 0; 3098: } else 3099: if(u.u_arg[0] == 0411) 3100: sep++; else 3101: if(u.u_arg[0] != 0410) { 3102: u.u_error = ENOEXEC; 3103: goto bad; 3104: } 3105: if(u.u_arg[1]!=0 && (ip->i_flag&ITEXT)==0 && ip->i_count!=1) { 3106: u.u_error = ETXTBSY; 3107: goto bad; 3108: } 3109: 3110: /* 3111: * find text and data sizes 3112: * try them out for possible 3113: * exceed of max sizes 3114: */ 3115: 3116: ts = ((u.u_arg[1]+63)>>6) & 01777; 3117: ds = ((u.u_arg[2]+u.u_arg[3]+63)>>6) & 01777; 3118: if(estabur(ts, ds, SSIZE, sep)) 3119: goto bad; 3120: 3121: /* 3122: * allocate and clear core 3123: * at this point, committed 3124: * to the new image 3125: */ 3126: 3127: u.u_prof[3] = 0; 3128: xfree(); 3129: expand(USIZE); 3130: xalloc(ip); 3131: c = USIZE+ds+SSIZE; 3132: expand(c); 3133: while(--c >= USIZE) 3134: clearseg(u.u_procp->p_addr+c); 3135: 3136: /* read in data segment */ 3137: 3138: estabur(0, ds, 0, 0); 3139: u.u_base = 0; 3140: u.u_offset[1] = 020+u.u_arg[1]; 3141: u.u_count = u.u_arg[2]; 3142: readi(ip); 3143: 3144: /* 3145: * initialize stack segment 3146: */ 3147: 3148: u.u_tsize = ts; 3149: u.u_dsize = ds; 3150: u.u_ssize = SSIZE; 3151: u.u_sep = sep; 3152: estabur(u.u_tsize, u.u_dsize, u.u_ssize, u.u_sep); 3153: cp = bp->b_addr; 3154: ap = -nc - na*2 - 4; 3155: u.u_ar0[R6] = ap; 3156: suword(ap, na); 3157: c = -nc; 3158: while(na--) { 3159: suword(ap=+2, c); 3160: do 3161: subyte(c++, *cp); 3162: while(*cp++); 3163: } 3164: suword(ap+2, -1); 3165: 3166: /* 3167: * set SUID/SGID protections, if no tracing 3168: */ 3169: 3170: if ((u.u_procp->p_flag&STRC)==0) { 3171: if(ip->i_mode&ISUID) 3172: if(u.u_uid != 0) { 3173: u.u_uid = ip->i_uid; 3174: u.u_procp->p_uid = ip->i_uid; 3175: } 3176: if(ip->i_mode&ISGID) 3177: u.u_gid = ip->i_gid; 3178: } 3179: 3180: /* clear sigs, regs and return */ 3181: 3182: c = ip; 3183: for(ip = &u.u_signal[0]; ip < &u.u_signal[NSIG]; ip++) 3184: if((*ip & 1) == 0) 3185: *ip = 0; 3186: for(cp = ®loc[0]; cp < ®loc[6];) 3187: u.u_ar0[*cp++] = 0; 3188: u.u_ar0[R7] = 0; 3189: for(ip = &u.u_fsav[0]; ip < &u.u_fsav[25];) 3190: *ip++ = 0; 3191: ip = c; 3192: 3193: bad: 3194: iput(ip); 3195: brelse(bp); 3196: if(execnt >= NEXEC) 3197: wakeup(&execnt); 3198: execnt--; 3199: } 3200: /* --------------------------- */ 3201: 3202: /* exit system call: 3203: * pass back caller's r0 3204: */ 3205: rexit() 3206: { 3207: 3208: u.u_arg[0] = u.u_ar0[R0] << 8; 3209: exit(); 3210: } 3211: /* --------------------------- */ 3212: 3213: /* Release resources. 3214: * Save u. area for parent to look at. 3215: * Enter zombie state. 3216: * Wake up parent and init processes, 3217: * and dispose of children. 3218: */ 3219: exit() 3220: { 3221: register int *q, a; 3222: register struct proc *p; 3223: 3224: u.u_procp->p_flag =& ~STRC; 3225: for(q = &u.u_signal[0]; q < &u.u_signal[NSIG];) 3226: *q++ = 1; 3227: for(q = &u.u_ofile[0]; q < &u.u_ofile[NOFILE]; q++) 3228: if(a = *q) { 3229: *q = NULL; 3230: closef(a); 3231: } 3232: iput(u.u_cdir); 3233: xfree(); 3234: a = malloc(swapmap, 1); 3235: if(a == NULL) 3236: panic("out of swap"); 3237: p = getblk(swapdev, a); 3238: bcopy(&u, p->b_addr, 256); 3239: bwrite(p); 3240: q = u.u_procp; 3241: mfree(coremap, q->p_size, q->p_addr); 3242: q->p_addr = a; 3243: q->p_stat = SZOMB; 3244: 3245: loop: 3246: for(p = &proc[0]; p < &proc[NPROC]; p++) 3247: if(q->p_ppid == p->p_pid) { 3248: wakeup(&proc[1]); 3249: wakeup(p); 3250: for(p = &proc[0]; p < &proc[NPROC]; p++) 3251: if(q->p_pid == p->p_ppid) { 3252: p->p_ppid = 1; 3253: if (p->p_stat == SSTOP) 3254: setrun(p); 3255: } 3256: swtch(); 3257: /* no return */ 3258: } 3259: q->p_ppid = 1; 3260: goto loop; 3261: } 3262: /* --------------------------- */ 3263: 3264: /* Wait system call. 3265: * Search for a terminated (zombie) child, 3266: * finally lay it to rest, and collect its status. 3267: * Look also for stopped (traced) children, 3268: * and pass back status from them. 3269: */ 3270: wait() 3271: { 3272: register f, *bp; 3273: register struct proc *p; 3274: 3275: f = 0; 3276: loop: 3277: for(p = &proc[0]; p < &proc[NPROC]; p++) 3278: if(p->p_ppid == u.u_procp->p_pid) { 3279: f++; 3280: if(p->p_stat == SZOMB) { 3281: u.u_ar0[R0] = p->p_pid; 3282: bp = bread(swapdev, f=p->p_addr); 3283: mfree(swapmap, 1, f); 3284: p->p_stat = NULL; 3285: p->p_pid = 0; 3286: p->p_ppid = 0; 3287: p->p_sig = 0; 3288: p->p_ttyp = 0; 3289: p->p_flag = 0; 3290: p = bp->b_addr; 3291: u.u_cstime[0] =+ p->u_cstime[0]; 3292: dpadd(u.u_cstime, p->u_cstime[1]); 3293: dpadd(u.u_cstime, p->u_stime); 3294: u.u_cutime[0] =+ p->u_cutime[0]; 3295: dpadd(u.u_cutime, p->u_cutime[1]); 3296: dpadd(u.u_cutime, p->u_utime); 3297: u.u_ar0[R1] = p->u_arg[0]; 3298: brelse(bp); 3299: return; 3300: } 3301: if(p->p_stat == SSTOP) { 3302: if((p->p_flag&SWTED) == 0) { 3303: p->p_flag =| SWTED; 3304: u.u_ar0[R0] = p->p_pid; 3305: u.u_ar0[R1] = (p->p_sig<<8) | 0177; 3306: return; 3307: } 3308: p->p_flag =& ~(STRC|SWTED); 3309: setrun(p); 3310: } 3311: } 3312: if(f) { 3313: sleep(u.u_procp, PWAIT); 3314: goto loop; 3315: } 3316: u.u_error = ECHILD; 3317: } 3318: /* --------------------------- */ 3319: 3320: /* fork system call. 3321: */ 3322: fork() 3323: { 3324: register struct proc *p1, *p2; 3325: 3326: p1 = u.u_procp; 3327: for(p2 = &proc[0]; p2 < &proc[NPROC]; p2++) 3328: if(p2->p_stat == NULL) 3329: goto found; 3330: u.u_error = EAGAIN; 3331: goto out; 3332: 3333: found: 3334: if(newproc()) { 3335: u.u_ar0[R0] = p1->p_pid; 3336: u.u_cstime[0] = 0; 3337: u.u_cstime[1] = 0; 3338: u.u_stime = 0; 3339: u.u_cutime[0] = 0; 3340: u.u_cutime[1] = 0; 3341: u.u_utime = 0; 3342: return; 3343: } 3344: u.u_ar0[R0] = p2->p_pid; 3345: 3346: out: 3347: u.u_ar0[R7] =+ 2; 3348: } 3349: /* --------------------------- */ 3350: 3351: /* break system call. 3352: * -- bad planning: "break" is a dirty word in C. 3353: */ 3354: sbreak() 3355: { 3356: register a, n, d; 3357: int i; 3358: 3359: /* set n to new data size 3360: * set d to new-old 3361: * set n to new total size 3362: */ 3363: 3364: n = (((u.u_arg[0]+63)>>6) & 01777); 3365: if(!u.u_sep) 3366: n =- nseg(u.u_tsize) * 128; 3367: if(n < 0) 3368: n = 0; 3369: d = n - u.u_dsize; 3370: n =+ USIZE+u.u_ssize; 3371: if(estabur(u.u_tsize, u.u_dsize+d, u.u_ssize, u.u_sep)) 3372: return; 3373: u.u_dsize =+ d; 3374: if(d > 0) 3375: goto bigger; 3376: a = u.u_procp->p_addr + n - u.u_ssize; 3377: i = n; 3378: n = u.u_ssize; 3379: while(n--) { 3380: copyseg(a-d, a); 3381: a++; 3382: } 3383: expand(i); 3384: return; 3385: 3386: bigger: 3387: expand(n); 3388: a = u.u_procp->p_addr + n; 3389: n = u.u_ssize; 3390: while(n--) { 3391: a--; 3392: copyseg(a-d, a); 3393: } 3394: while(d--) 3395: clearseg(--a); 3396: } 3397: /* --------------------------- */