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

  1. #
  2. /*
  3.  */
  4.  
  5. #include "../param.h"
  6. #include "../inode.h"
  7. #include "../user.h"
  8. #include "../buf.h"
  9. #include "../conf.h"
  10. #include "../systm.h"
  11.  
  12. /*
  13.  * Read the file corresponding to
  14.  * the inode pointed at by the argument.
  15.  * The actual read arguments are found
  16.  * in the variables:
  17.  *    u_base        core address for destination
  18.  *    u_offset    byte offset in file
  19.  *    u_count        number of bytes to read
  20.  *    u_segflg    read to kernel/user
  21.  */
  22. readi(aip)
  23. struct inode *aip;
  24. {
  25.     int *bp;
  26.     int lbn, bn, on;
  27.     register dn, n;
  28.     register struct inode *ip;
  29.  
  30.     ip = aip;
  31.     if(u.u_count == 0)
  32.         return;
  33.     ip->i_flag =| IACC;
  34.     if((ip->i_mode&IFMT) == IFCHR) {
  35.         (*cdevsw[ip->i_addr[0].d_major].d_read)(ip->i_addr[0]);
  36.         return;
  37.     }
  38.  
  39.     do {
  40.         lbn = bn = lshift(u.u_offset, -9);
  41.         on = u.u_offset[1] & 0777;
  42.         n = min(512-on, u.u_count);
  43.         if((ip->i_mode&IFMT) != IFBLK) {
  44.             dn = dpcmp(ip->i_size0&0377, ip->i_size1,
  45.                 u.u_offset[0], u.u_offset[1]);
  46.             if(dn <= 0)
  47.                 return;
  48.             n = min(n, dn);
  49.             if ((bn = bmap(ip, lbn)) == 0)
  50.                 return;
  51.             dn = ip->i_dev;
  52.         } else {
  53.             dn = ip->i_addr[0];
  54.             rablock = bn+1;
  55.         }
  56.         if (ip->i_lastr+1 == lbn)
  57.             bp = breada(dn, bn, rablock);
  58.         else
  59.             bp = bread(dn, bn);
  60.         ip->i_lastr = lbn;
  61.         iomove(bp, on, n, B_READ);
  62.         brelse(bp);
  63.     } while(u.u_error==0 && u.u_count!=0);
  64. }
  65.  
  66. /*
  67.  * Write the file corresponding to
  68.  * the inode pointed at by the argument.
  69.  * The actual write arguments are found
  70.  * in the variables:
  71.  *    u_base        core address for source
  72.  *    u_offset    byte offset in file
  73.  *    u_count        number of bytes to write
  74.  *    u_segflg    write to kernel/user
  75.  */
  76. writei(aip)
  77. struct inode *aip;
  78. {
  79.     int *bp;
  80.     int n, on;
  81.     register dn, bn;
  82.     register struct inode *ip;
  83.  
  84.     ip = aip;
  85.     ip->i_flag =| IACC|IUPD;
  86.     if((ip->i_mode&IFMT) == IFCHR) {
  87.         (*cdevsw[ip->i_addr[0].d_major].d_write)(ip->i_addr[0]);
  88.         return;
  89.     }
  90.     if (u.u_count == 0)
  91.         return;
  92.  
  93.     do {
  94.         bn = lshift(u.u_offset, -9);
  95.         on = u.u_offset[1] & 0777;
  96.         n = min(512-on, u.u_count);
  97.         if((ip->i_mode&IFMT) != IFBLK) {
  98.             if ((bn = bmap(ip, bn)) == 0)
  99.                 return;
  100.             dn = ip->i_dev;
  101.         } else
  102.             dn = ip->i_addr[0];
  103.         if(n == 512) 
  104.             bp = getblk(dn, bn); else
  105.             bp = bread(dn, bn);
  106.         iomove(bp, on, n, B_WRITE);
  107.         if(u.u_error != 0)
  108.             brelse(bp); else
  109.         if ((u.u_offset[1]&0777)==0)
  110.             bawrite(bp); else
  111.             bdwrite(bp);
  112.         if(dpcmp(ip->i_size0&0377, ip->i_size1,
  113.           u.u_offset[0], u.u_offset[1]) < 0 &&
  114.           (ip->i_mode&(IFBLK&IFCHR)) == 0) {
  115.             ip->i_size0 = u.u_offset[0];
  116.             ip->i_size1 = u.u_offset[1];
  117.         }
  118.         ip->i_flag =| IUPD;
  119.     } while(u.u_error==0 && u.u_count!=0);
  120. }
  121.  
  122. /*
  123.  * Return the logical maximum
  124.  * of the 2 arguments.
  125.  */
  126. max(a, b)
  127. char *a, *b;
  128. {
  129.  
  130.     if(a > b)
  131.         return(a);
  132.     return(b);
  133. }
  134.  
  135. /*
  136.  * Return the logical minimum
  137.  * of the 2 arguments.
  138.  */
  139. min(a, b)
  140. char *a, *b;
  141. {
  142.  
  143.     if(a < b)
  144.         return(a);
  145.     return(b);
  146. }
  147.  
  148. /*
  149.  * Move 'an' bytes at byte location
  150.  * &bp->b_addr[o] to/from (flag) the
  151.  * user/kernel (u.segflg) area starting at u.base.
  152.  * Update all the arguments by the number
  153.  * of bytes moved.
  154.  *
  155.  * There are 2 algorithms,
  156.  * if source address, dest address and count
  157.  * are all even in a user copy,
  158.  * then the machine language copyin/copyout
  159.  * is called.
  160.  * If not, its done byte-by-byte with
  161.  * cpass and passc.
  162.  */
  163. iomove(bp, o, an, flag)
  164. struct buf *bp;
  165. {
  166.     register char *cp;
  167.     register int n, t;
  168.  
  169.     n = an;
  170.     cp = bp->b_addr + o;
  171.     if(u.u_segflg==0 && ((n | cp | u.u_base)&01)==0) {
  172.         if (flag==B_WRITE)
  173.             cp = copyin(u.u_base, cp, n);
  174.         else
  175.             cp = copyout(cp, u.u_base, n);
  176.         if (cp) {
  177.             u.u_error = EFAULT;
  178.             return;
  179.         }
  180.         u.u_base =+ n;
  181.         dpadd(u.u_offset, n);
  182.         u.u_count =- n;
  183.         return;
  184.     }
  185.     if (flag==B_WRITE) {
  186.         while(n--) {
  187.             if ((t = cpass()) < 0)
  188.                 return;
  189.             *cp++ = t;
  190.         }
  191.     } else
  192.         while (n--)
  193.             if(passc(*cp++) < 0)
  194.                 return;
  195. }
  196.