fio.c

6600 # 6601 /* 6602 */ 6603 6604 #include "../param.h" 6605 #include "../user.h" 6606 #include "../filsys.h" 6607 #include "../file.h" 6608 #include "../conf.h" 6609 #include "../inode.h" 6610 #include "../reg.h" 6611 6612 /* 6613 * Convert a user supplied 6614 * file descriptor into a pointer 6615 * to a file structure. 6616 * Only task is to check range 6617 * of the descriptor. 6618 */ 6619 getf(f) 6620 { 6621 register *fp, rf; 6622 6623 rf = f; 6624 if(rf<0 || rf>=NOFILE) 6625 goto bad; 6626 fp = u.u_ofile[rf]; 6627 if(fp != NULL) 6628 return(fp); 6629 bad: 6630 u.u_error = EBADF; 6631 return(NULL); 6632 } 6633 /* ------------------------ */ 6634 6635 /* 6636 * Internal form of close. 6637 * Decrement reference count on 6638 * file structure and call closei 6639 * on last closef. 6640 * Also make sure the pipe protocol 6641 * does not constipate. 6642 */ 6643 closef(fp) 6644 int *fp; 6645 { 6646 register *rfp, *ip; 6647 6648 rfp = fp; 6649 if(rfp->f_flag&FPIPE) { 6650 ip = rfp->f_inode; 6651 ip->i_mode =& ~(IREAD|IWRITE); 6652 wakeup(ip+1); 6653 wakeup(ip+2); 6654 } 6655 if(rfp->f_count <= 1) 6656 closei(rfp->f_inode, rfp->f_flag&FWRITE); 6657 rfp->f_count--; 6658 } 6659 /* ------------------------ */ 6660 6661 /* 6662 * Decrement reference count on an 6663 * inode due to the removal of a 6664 * referencing file structure. 6665 * On the last closei, switchout 6666 * to the close entry point of special 6667 * device handler. 6668 * Note that the handler gets called 6669 * on every open and only on the last 6670 * close. 6671 */ 6672 closei(ip, rw) 6673 int *ip; 6674 { 6675 register *rip; 6676 register dev, maj; 6677 6678 rip = ip; 6679 dev = rip->i_addr[0]; 6680 maj = rip->i_addr[0].d_major; 6681 if(rip->i_count <= 1) 6682 switch(rip->i_mode&IFMT) { 6683 6684 case IFCHR: 6685 (*cdevsw[maj].d_close)(dev, rw); 6686 break; 6687 6688 case IFBLK: 6689 (*bdevsw[maj].d_close)(dev, rw); 6690 } 6691 iput(rip); 6692 } 6693 /* ------------------------ */ 6694 6695 /* 6696 * openi called to allow handler 6697 * of special files to initialize and 6698 * validate before actual IO. 6699 * Called on all sorts of opens 6700 * and also on mount. 6701 */ 6702 openi(ip, rw) 6703 int *ip; 6704 { 6705 register *rip; 6706 register dev, maj; 6707 6708 rip = ip; 6709 dev = rip->i_addr[0]; 6710 maj = rip->i_addr[0].d_major; 6711 switch(rip->i_mode&IFMT) { 6712 6713 case IFCHR: 6714 if(maj >= nchrdev) 6715 goto bad; 6716 (*cdevsw[maj].d_open)(dev, rw); 6717 break; 6718 6719 case IFBLK: 6720 if(maj >= nblkdev) 6721 goto bad; 6722 (*bdevsw[maj].d_open)(dev, rw); 6723 } 6724 return; 6725 6726 bad: 6727 u.u_error = ENXIO; 6728 } 6729 /* ------------------------ */ 6730 6731 /* 6732 * Check mode permission on inode pointer. 6733 * Mode is READ, WRITE or EXEC. 6734 * In the case of WRITE, the 6735 * read-only status of the file 6736 * system is checked. 6737 * Also in WRITE, prototype text 6738 * segments cannot be written. 6739 * The mode is shifted to select 6740 * the owner/group/other fields. 6741 * The super user is granted all 6742 * permissions except for EXEC where 6743 * at least one of the EXEC bits must 6744 * be on. 6745 */ 6746 access(aip, mode) 6747 int *aip; 6748 { 6749 register *ip, m; 6750 6751 ip = aip; 6752 m = mode; 6753 if(m == IWRITE) { 6754 if(getfs(ip->i_dev)->s_ronly != 0) { 6755 u.u_error = EROFS; 6756 return(1); 6757 } 6758 if(ip->i_flag & ITEXT) { 6759 u.u_error = ETXTBSY; 6760 return(1); 6761 } 6762 } 6763 if(u.u_uid == 0) { 6764 if(m == IEXEC && (ip->i_mode & 6765 (IEXEC | (IEXEC>>3) | (IEXEC>>6))) == 0) 6766 goto bad; 6767 return(0); 6768 } 6769 if(u.u_uid != ip->i_uid) { 6770 m =>> 3; 6771 if(u.u_gid != ip->i_gid) 6772 m =>> 3; 6773 } 6774 if((ip->i_mode&m) != 0) 6775 return(0); 6776 6777 bad: 6778 u.u_error = EACCES; 6779 return(1); 6780 } 6781 /* ------------------------ */ 6782 6783 /* 6784 * Look up a pathname and test if 6785 * the resultant inode is owned by the 6786 * current user. 6787 * If not, try for super-user. 6788 * If permission is granted, 6789 * return inode pointer. 6790 */ 6791 owner() 6792 { 6793 register struct inode *ip; 6794 extern uchar(); 6795 6796 if ((ip = namei(uchar, 0)) == NULL) 6797 return(NULL); 6798 if(u.u_uid == ip->i_uid) 6799 return(ip); 6800 if (suser()) 6801 return(ip); 6802 iput(ip); 6803 return(NULL); 6804 } 6805 /* ------------------------ */ 6806 6807 /* 6808 * Test if the current user is the 6809 * super user. 6810 */ 6811 suser() 6812 { 6813 6814 if(u.u_uid == 0) 6815 return(1); 6816 u.u_error = EPERM; 6817 return(0); 6818 } 6819 /* ------------------------ */ 6820 6821 /* 6822 * Allocate a user file descriptor. 6823 */ 6824 ufalloc() 6825 { 6826 register i; 6827 6828 for (i=0; i<NOFILE; i++) 6829 if (u.u_ofile[i] == NULL) { 6830 u.u_ar0[R0] = i; 6831 return(i); 6832 } 6833 u.u_error = EMFILE; 6834 return(-1); 6835 } 6836 /* ------------------------ */ 6837 6838 /* 6839 * Allocate a user file descriptor 6840 * and a file structure. 6841 * Initialize the descriptor 6842 * to point at the file structure. 6843 * 6844 * no file -- if there are no available 6845 * file structures. 6846 */ 6847 falloc() 6848 { 6849 register struct file *fp; 6850 register i; 6851 6852 if ((i = ufalloc()) < 0) 6853 return(NULL); 6854 for (fp = &file[0]; fp < &file[NFILE]; fp++) 6855 if (fp->f_count==0) { 6856 u.u_ofile[i] = fp; 6857 fp->f_count++; 6858 fp->f_offset[0] = 0; 6859 fp->f_offset[1] = 0; 6860 return(fp); 6861 } 6862 printf("no file\n"); 6863 u.u_error = ENFILE; 6864 return(NULL); 6865 } 6866 /* ------------------------ */ 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899