home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V6 / usr / sys / ken / sys1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1975-07-18  |  6.8 KB  |  408 lines

  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. }
  408.