sys/sys2.c

06650 #include "../h/param.h" 06651 #include "../h/systm.h" 06652 #include "../h/dir.h" 06653 #include "../h/user.h" 06654 #include "../h/reg.h" 06655 #include "../h/file.h" 06656 #include "../h/inode.h" 06657 06658 /* 06659 * read system call 06660 */ 06661 read() 06662 { 06663 rdwr(FREAD); 06664 } 06665 06666 /* 06667 * write system call 06668 */ 06669 write() 06670 { 06671 rdwr(FWRITE); 06672 } 06673 06674 /* 06675 * common code for read and write calls: 06676 * check permissions, set base, count, and offset, 06677 * and switch out to readi, writei, or pipe code. 06678 */ 06679 rdwr(mode) 06680 register mode; 06681 { 06682 register struct file *fp; 06683 register struct inode *ip; 06684 register struct a { 06685 int fdes; 06686 char *cbuf; 06687 unsigned count; 06688 } *uap; 06689 06690 uap = (struct a *)u.u_ap; 06691 fp = getf(uap->fdes); 06692 if(fp == NULL) 06693 return; 06694 if((fp->f_flag&mode) == 0) { 06695 u.u_error = EBADF; 06696 return; 06697 } 06698 u.u_base = (caddr_t)uap->cbuf; 06699 u.u_count = uap->count; 06700 u.u_segflg = 0; 06701 if((fp->f_flag&FPIPE) != 0) { 06702 if(mode == FREAD) 06703 readp(fp); 06704 else 06705 writep(fp); 06706 } else { 06707 ip = fp->f_inode; 06708 if (fp->f_flag&FMP) 06709 u.u_offset = 0; 06710 else 06711 u.u_offset = fp->f_un.f_offset; 06712 if((ip->i_mode&(IFCHR&IFBLK)) == 0) 06713 plock(ip); 06714 if(mode == FREAD) 06715 readi(ip); 06716 else 06717 writei(ip); 06718 if((ip->i_mode&(IFCHR&IFBLK)) == 0) 06719 prele(ip); 06720 if ((fp->f_flag&FMP) == 0) 06721 fp->f_un.f_offset += uap->count-u.u_count; 06722 } 06723 u.u_r.r_val1 = uap->count-u.u_count; 06724 } 06725 06726 /* 06727 * open system call 06728 */ 06729 open() 06730 { 06731 register struct inode *ip; 06732 register struct a { 06733 char *fname; 06734 int rwmode; 06735 } *uap; 06736 06737 uap = (struct a *)u.u_ap; 06738 ip = namei(uchar, 0); 06739 if(ip == NULL) 06740 return; 06741 open1(ip, ++uap->rwmode, 0); 06742 } 06743 06744 /* 06745 * creat system call 06746 */ 06747 creat() 06748 { 06749 register struct inode *ip; 06750 register struct a { 06751 char *fname; 06752 int fmode; 06753 } *uap; 06754 06755 uap = (struct a *)u.u_ap; 06756 ip = namei(uchar, 1); 06757 if(ip == NULL) { 06758 if(u.u_error) 06759 return; 06760 ip = maknode(uap->fmode&07777&(~ISVTX)); 06761 if (ip==NULL) 06762 return; 06763 open1(ip, FWRITE, 2); 06764 } else 06765 open1(ip, FWRITE, 1); 06766 } 06767 06768 /* 06769 * common code for open and creat. 06770 * Check permissions, allocate an open file structure, 06771 * and call the device open routine if any. 06772 */ 06773 open1(ip, mode, trf) 06774 register struct inode *ip; 06775 register mode; 06776 { 06777 register struct file *fp; 06778 int i; 06779 06780 if(trf != 2) { 06781 if(mode&FREAD) 06782 access(ip, IREAD); 06783 if(mode&FWRITE) { 06784 access(ip, IWRITE); 06785 if((ip->i_mode&IFMT) == IFDIR) 06786 u.u_error = EISDIR; 06787 } 06788 } 06789 if(u.u_error) 06790 goto out; 06791 if(trf == 1) 06792 itrunc(ip); 06793 prele(ip); 06794 if ((fp = falloc()) == NULL) 06795 goto out; 06796 fp->f_flag = mode&(FREAD|FWRITE); 06797 fp->f_inode = ip; 06798 i = u.u_r.r_val1; 06799 openi(ip, mode&FWRITE); 06800 if(u.u_error == 0) 06801 return; 06802 u.u_ofile[i] = NULL; 06803 fp->f_count--; 06804 06805 out: 06806 iput(ip); 06807 } 06808 06809 /* 06810 * close system call 06811 */ 06812 close() 06813 { 06814 register struct file *fp; 06815 register struct a { 06816 int fdes; 06817 } *uap; 06818 06819 uap = (struct a *)u.u_ap; 06820 fp = getf(uap->fdes); 06821 if(fp == NULL) 06822 return; 06823 u.u_ofile[uap->fdes] = NULL; 06824 closef(fp); 06825 } 06826 06827 /* 06828 * seek system call 06829 */ 06830 seek() 06831 { 06832 register struct file *fp; 06833 register struct a { 06834 int fdes; 06835 off_t off; 06836 int sbase; 06837 } *uap; 06838 06839 uap = (struct a *)u.u_ap; 06840 fp = getf(uap->fdes); 06841 if(fp == NULL) 06842 return; 06843 if(fp->f_flag&(FPIPE|FMP)) { 06844 u.u_error = ESPIPE; 06845 return; 06846 } 06847 if(uap->sbase == 1) 06848 uap->off += fp->f_un.f_offset; 06849 else if(uap->sbase == 2) 06850 uap->off += fp->f_inode->i_size; 06851 fp->f_un.f_offset = uap->off; 06852 u.u_r.r_off = uap->off; 06853 } 06854 06855 /* 06856 * link system call 06857 */ 06858 link() 06859 { 06860 register struct inode *ip, *xp; 06861 register struct a { 06862 char *target; 06863 char *linkname; 06864 } *uap; 06865 06866 uap = (struct a *)u.u_ap; 06867 ip = namei(uchar, 0); 06868 if(ip == NULL) 06869 return; 06870 if((ip->i_mode&IFMT)==IFDIR && !suser()) 06871 goto out; 06872 /* 06873 * Unlock to avoid possibly hanging the namei. 06874 * Sadly, this means races. (Suppose someone 06875 * deletes the file in the meantime?) 06876 * Nor can it be locked again later 06877 * because then there will be deadly 06878 * embraces. 06879 */ 06880 prele(ip); 06881 u.u_dirp = (caddr_t)uap->linkname; 06882 xp = namei(uchar, 1); 06883 if(xp != NULL) { 06884 u.u_error = EEXIST; 06885 iput(xp); 06886 goto out; 06887 } 06888 if (u.u_error) 06889 goto out; 06890 if(u.u_pdir->i_dev != ip->i_dev) { 06891 iput(u.u_pdir); 06892 u.u_error = EXDEV; 06893 goto out; 06894 } 06895 wdir(ip); 06896 if (u.u_error==0) { 06897 ip->i_nlink++; 06898 ip->i_flag |= ICHG; 06899 } 06900 06901 out: 06902 iput(ip); 06903 } 06904 06905 /* 06906 * mknod system call 06907 */ 06908 mknod() 06909 { 06910 register struct inode *ip; 06911 register struct a { 06912 char *fname; 06913 int fmode; 06914 int dev; 06915 } *uap; 06916 06917 uap = (struct a *)u.u_ap; 06918 if(suser()) { 06919 ip = namei(uchar, 1); 06920 if(ip != NULL) { 06921 u.u_error = EEXIST; 06922 goto out; 06923 } 06924 } 06925 if(u.u_error) 06926 return; 06927 ip = maknode(uap->fmode); 06928 if (ip == NULL) 06929 return; 06930 ip->i_un.i_rdev = (dev_t)uap->dev; 06931 06932 out: 06933 iput(ip); 06934 } 06935 06936 /* 06937 * access system call 06938 */ 06939 saccess() 06940 { 06941 register svuid, svgid; 06942 register struct inode *ip; 06943 register struct a { 06944 char *fname; 06945 int fmode; 06946 } *uap; 06947 06948 uap = (struct a *)u.u_ap; 06949 svuid = u.u_uid; 06950 svgid = u.u_gid; 06951 u.u_uid = u.u_ruid; 06952 u.u_gid = u.u_rgid; 06953 ip = namei(uchar, 0); 06954 if (ip != NULL) { 06955 if (uap->fmode&(IREAD>>6)) 06956 access(ip, IREAD); 06957 if (uap->fmode&(IWRITE>>6)) 06958 access(ip, IWRITE); 06959 if (uap->fmode&(IEXEC>>6)) 06960 access(ip, IEXEC); 06961 iput(ip); 06962 } 06963 u.u_uid = svuid; 06964 u.u_gid = svgid; 06965 } 06966 06967 06968 06969 06970 06971 06972 06973 06974 06975 06976 06977 06978 06979 06980 06981 06982 06983 06984 06985 06986 06987 06988 06989 06990 06991 06992 06993 06994 06995 06996 06997 06998 06999