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

  1. #
  2. /*
  3.  */
  4.  
  5. #include "../param.h"
  6. #include "../user.h"
  7. #include "../filsys.h"
  8. #include "../file.h"
  9. #include "../conf.h"
  10. #include "../inode.h"
  11. #include "../reg.h"
  12.  
  13. /*
  14.  * Convert a user supplied
  15.  * file descriptor into a pointer
  16.  * to a file structure.
  17.  * Only task is to check range
  18.  * of the descriptor.
  19.  */
  20. getf(f)
  21. {
  22.     register *fp, rf;
  23.  
  24.     rf = f;
  25.     if(rf<0 || rf>=NOFILE)
  26.         goto bad;
  27.     fp = u.u_ofile[rf];
  28.     if(fp != NULL)
  29.         return(fp);
  30. bad:
  31.     u.u_error = EBADF;
  32.     return(NULL);
  33. }
  34.  
  35. /*
  36.  * Internal form of close.
  37.  * Decrement reference count on
  38.  * file structure and call closei
  39.  * on last closef.
  40.  * Also make sure the pipe protocol
  41.  * does not constipate.
  42.  */
  43. closef(fp)
  44. int *fp;
  45. {
  46.     register *rfp, *ip;
  47.  
  48.     rfp = fp;
  49.     if(rfp->f_flag&FPIPE) {
  50.         ip = rfp->f_inode;
  51.         ip->i_mode =& ~(IREAD|IWRITE);
  52.         wakeup(ip+1);
  53.         wakeup(ip+2);
  54.     }
  55.     if(rfp->f_count <= 1)
  56.         closei(rfp->f_inode, rfp->f_flag&FWRITE);
  57.     rfp->f_count--;
  58. }
  59.  
  60. /*
  61.  * Decrement reference count on an
  62.  * inode due to the removal of a
  63.  * referencing file structure.
  64.  * On the last closei, switchout
  65.  * to the close entry point of special
  66.  * device handler.
  67.  * Note that the handler gets called
  68.  * on every open and only on the last
  69.  * close.
  70.  */
  71. closei(ip, rw)
  72. int *ip;
  73. {
  74.     register *rip;
  75.     register dev, maj;
  76.  
  77.     rip = ip;
  78.     dev = rip->i_addr[0];
  79.     maj = rip->i_addr[0].d_major;
  80.     if(rip->i_count <= 1)
  81.     switch(rip->i_mode&IFMT) {
  82.  
  83.     case IFCHR:
  84.         (*cdevsw[maj].d_close)(dev, rw);
  85.         break;
  86.  
  87.     case IFBLK:
  88.         (*bdevsw[maj].d_close)(dev, rw);
  89.     }
  90.     iput(rip);
  91. }
  92.  
  93. /*
  94.  * openi called to allow handler
  95.  * of special files to initialize and
  96.  * validate before actual IO.
  97.  * Called on all sorts of opens
  98.  * and also on mount.
  99.  */
  100. openi(ip, rw)
  101. int *ip;
  102. {
  103.     register *rip;
  104.     register dev, maj;
  105.  
  106.     rip = ip;
  107.     dev = rip->i_addr[0];
  108.     maj = rip->i_addr[0].d_major;
  109.     switch(rip->i_mode&IFMT) {
  110.  
  111.     case IFCHR:
  112.         if(maj >= nchrdev)
  113.             goto bad;
  114.         (*cdevsw[maj].d_open)(dev, rw);
  115.         break;
  116.  
  117.     case IFBLK:
  118.         if(maj >= nblkdev)
  119.             goto bad;
  120.         (*bdevsw[maj].d_open)(dev, rw);
  121.     }
  122.     return;
  123.  
  124. bad:
  125.     u.u_error = ENXIO;
  126. }
  127.  
  128. /*
  129.  * Check mode permission on inode pointer.
  130.  * Mode is READ, WRITE or EXEC.
  131.  * In the case of WRITE, the
  132.  * read-only status of the file
  133.  * system is checked.
  134.  * Also in WRITE, prototype text
  135.  * segments cannot be written.
  136.  * The mode is shifted to select
  137.  * the owner/group/other fields.
  138.  * The super user is granted all
  139.  * permissions except for EXEC where
  140.  * at least one of the EXEC bits must
  141.  * be on.
  142.  */
  143. access(aip, mode)
  144. int *aip;
  145. {
  146.     register *ip, m;
  147.  
  148.     ip = aip;
  149.     m = mode;
  150.     if(m == IWRITE) {
  151.         if(getfs(ip->i_dev)->s_ronly != 0) {
  152.             u.u_error = EROFS;
  153.             return(1);
  154.         }
  155.         if(ip->i_flag & ITEXT) {
  156.             u.u_error = ETXTBSY;
  157.             return(1);
  158.         }
  159.     }
  160.     if(u.u_uid == 0) {
  161.         if(m == IEXEC && (ip->i_mode & 
  162.             (IEXEC | (IEXEC>>3) | (IEXEC>>6))) == 0)
  163.                 goto bad;
  164.         return(0);
  165.     }
  166.     if(u.u_uid != ip->i_uid) {
  167.         m =>> 3;
  168.         if(u.u_gid != ip->i_gid)
  169.             m =>> 3;
  170.     }
  171.     if((ip->i_mode&m) != 0)
  172.         return(0);
  173.  
  174. bad:
  175.     u.u_error = EACCES;
  176.     return(1);
  177. }
  178.  
  179. /*
  180.  * Look up a pathname and test if
  181.  * the resultant inode is owned by the
  182.  * current user.
  183.  * If not, try for super-user.
  184.  * If permission is granted,
  185.  * return inode pointer.
  186.  */
  187. owner()
  188. {
  189.     register struct inode *ip;
  190.     extern uchar();
  191.  
  192.     if ((ip = namei(uchar, 0)) == NULL)
  193.         return(NULL);
  194.     if(u.u_uid == ip->i_uid)
  195.         return(ip);
  196.     if (suser())
  197.         return(ip);
  198.     iput(ip);
  199.     return(NULL);
  200. }
  201.  
  202. /*
  203.  * Test if the current user is the
  204.  * super user.
  205.  */
  206. suser()
  207. {
  208.  
  209.     if(u.u_uid == 0)
  210.         return(1);
  211.     u.u_error = EPERM;
  212.     return(0);
  213. }
  214.  
  215. /*
  216.  * Allocate a user file descriptor.
  217.  */
  218. ufalloc()
  219. {
  220.     register i;
  221.  
  222.     for (i=0; i<NOFILE; i++)
  223.         if (u.u_ofile[i] == NULL) {
  224.             u.u_ar0[R0] = i;
  225.             return(i);
  226.         }
  227.     u.u_error = EMFILE;
  228.     return(-1);
  229. }
  230.  
  231. /*
  232.  * Allocate a user file descriptor
  233.  * and a file structure.
  234.  * Initialize the descriptor
  235.  * to point at the file structure.
  236.  *
  237.  * no file -- if there are no available
  238.  *     file structures.
  239.  */
  240. falloc()
  241. {
  242.     register struct file *fp;
  243.     register i;
  244.  
  245.     if ((i = ufalloc()) < 0)
  246.         return(NULL);
  247.     for (fp = &file[0]; fp < &file[NFILE]; fp++)
  248.         if (fp->f_count==0) {
  249.             u.u_ofile[i] = fp;
  250.             fp->f_count++;
  251.             fp->f_offset[0] = 0;
  252.             fp->f_offset[1] = 0;
  253.             return(fp);
  254.         }
  255.     printf("no file\n");
  256.     u.u_error = ENFILE;
  257.     return(NULL);
  258. }
  259.