5700 # 5701 #include "../param.h" 5702 #include "../systm.h" 5703 #include "../user.h" 5704 #include "../reg.h" 5705 #include "../file.h" 5706 #include "../inode.h" 5707 5708 /* 5709 * read system call 5710 */ 5711 read() 5712 { 5713 rdwr(FREAD); 5714 } 5715 /* ------------------------ */ 5716 5717 /* 5718 * write system call 5719 */ 5720 write() 5721 { 5722 rdwr(FWRITE); 5723 } 5724 /* ------------------------ */ 5725 5726 /* 5727 * common code for read and write calls: 5728 * check permissions, set base, count, and offset, 5729 * and switch out to readi, writei, or pipe code. 5730 */ 5731 rdwr(mode) 5732 { 5733 register *fp, m; 5734 5735 m = mode; 5736 fp = getf(u.u_ar0[R0]); 5737 if(fp == NULL) 5738 return; 5739 if((fp->f_flag&m) == 0) { 5740 u.u_error = EBADF; 5741 return; 5742 } 5743 u.u_base = u.u_arg[0]; 5744 u.u_count = u.u_arg[1]; 5745 u.u_segflg = 0; 5746 if(fp->f_flag&FPIPE) { 5747 if(m==FREAD) 5748 readp(fp); else 5749 writep(fp); 5750 } else { 5751 u.u_offset[1] = fp->f_offset[1]; 5752 u.u_offset[0] = fp->f_offset[0]; 5753 if(m==FREAD) 5754 readi(fp->f_inode); else 5755 writei(fp->f_inode); 5756 dpadd(fp->f_offset, u.u_arg[1]-u.u_count); 5757 } 5758 u.u_ar0[R0] = u.u_arg[1]-u.u_count; 5759 } 5760 /* ------------------------ */ 5761 5762 /* 5763 * open system call 5764 */ 5765 open() 5766 { 5767 register *ip; 5768 extern uchar; 5769 5770 ip = namei(&uchar, 0); 5771 if(ip == NULL) 5772 return; 5773 u.u_arg[1]++; 5774 open1(ip, u.u_arg[1], 0); 5775 } 5776 /* ------------------------ */ 5777 5778 /* 5779 * creat system call 5780 */ 5781 creat() 5782 { 5783 register *ip; 5784 extern uchar; 5785 5786 ip = namei(&uchar, 1); 5787 if(ip == NULL) { 5788 if(u.u_error) 5789 return; 5790 ip = maknode(u.u_arg[1]&07777&(~ISVTX)); 5791 if (ip==NULL) 5792 return; 5793 open1(ip, FWRITE, 2); 5794 } else 5795 open1(ip, FWRITE, 1); 5796 } 5797 /* ------------------------ */ 5798 5799 /* 5800 * common code for open and creat. 5801 * Check permissions, allocate an open file structure, 5802 * and call the device open routine if any. 5803 */ 5804 open1(ip, mode, trf) 5805 int *ip; 5806 { 5807 register struct file *fp; 5808 register *rip, m; 5809 int i; 5810 5811 rip = ip; 5812 m = mode; 5813 if(trf != 2) { 5814 if(m&FREAD) 5815 access(rip, IREAD); 5816 if(m&FWRITE) { 5817 access(rip, IWRITE); 5818 if((rip->i_mode&IFMT) == IFDIR) 5819 u.u_error = EISDIR; 5820 } 5821 } 5822 if(u.u_error) 5823 goto out; 5824 if(trf) 5825 itrunc(rip); 5826 prele(rip); 5827 if ((fp = falloc()) == NULL) 5828 goto out; 5829 fp->f_flag = m&(FREAD|FWRITE); 5830 fp->f_inode = rip; 5831 i = u.u_ar0[R0]; 5832 openi(rip, m&FWRITE); 5833 if(u.u_error == 0) 5834 return; 5835 u.u_ofile[i] = NULL; 5836 fp->f_count--; 5837 5838 out: 5839 iput(rip); 5840 } 5841 /* ------------------------ */ 5842 5843 /* 5844 * close system call 5845 */ 5846 close() 5847 { 5848 register *fp; 5849 5850 fp = getf(u.u_ar0[R0]); 5851 if(fp == NULL) 5852 return; 5853 u.u_ofile[u.u_ar0[R0]] = NULL; 5854 closef(fp); 5855 } 5856 /* ------------------------ */ 5857 5858 /* 5859 * seek system call 5860 */ 5861 seek() 5862 { 5863 int n[2]; 5864 register *fp, t; 5865 5866 fp = getf(u.u_ar0[R0]); 5867 if(fp == NULL) 5868 return; 5869 if(fp->f_flag&FPIPE) { 5870 u.u_error = ESPIPE; 5871 return; 5872 } 5873 t = u.u_arg[1]; 5874 if(t > 2) { 5875 n[1] = u.u_arg[0]<<9; 5876 n[0] = u.u_arg[0]>>7; 5877 if(t == 3) 5878 n[0] =& 0777; 5879 } else { 5880 n[1] = u.u_arg[0]; 5881 n[0] = 0; 5882 if(t!=0 && n[1]<0) 5883 n[0] = -1; 5884 } 5885 switch(t) { 5886 5887 case 1: 5888 case 4: 5889 n[0] =+ fp->f_offset[0]; 5890 dpadd(n, fp->f_offset[1]); 5891 break; 5892 5893 default: 5894 n[0] =+ fp->f_inode->i_size0&0377; 5895 dpadd(n, fp->f_inode->i_size1); 5896 5897 case 0: 5898 case 3: 5899 ; 5900 } 5901 fp->f_offset[1] = n[1]; 5902 fp->f_offset[0] = n[0]; 5903 } 5904 /* ------------------------ */ 5905 5906 /* 5907 * link system call 5908 */ 5909 link() 5910 { 5911 register *ip, *xp; 5912 extern uchar; 5913 5914 ip = namei(&uchar, 0); 5915 if(ip == NULL) 5916 return; 5917 if(ip->i_nlink >= 127) { 5918 u.u_error = EMLINK; 5919 goto out; 5920 } 5921 if((ip->i_mode&IFMT)==IFDIR && !suser()) 5922 goto out; 5923 /* 5924 * unlock to avoid possibly hanging the namei 5925 */ 5926 ip->i_flag =& ~ILOCK; 5927 u.u_dirp = u.u_arg[1]; 5928 xp = namei(&uchar, 1); 5929 if(xp != NULL) { 5930 u.u_error = EEXIST; 5931 iput(xp); 5932 } 5933 if(u.u_error) 5934 goto out; 5935 if(u.u_pdir->i_dev != ip->i_dev) { 5936 iput(u.u_pdir); 5937 u.u_error = EXDEV; 5938 goto out; 5939 } 5940 wdir(ip); 5941 ip->i_nlink++; 5942 ip->i_flag =| IUPD; 5943 5944 out: 5945 iput(ip); 5946 } 5947 /* ------------------------ */ 5948 5949 /* 5950 * mknod system call 5951 */ 5952 mknod() 5953 { 5954 register *ip; 5955 extern uchar; 5956 5957 if(suser()) { 5958 ip = namei(&uchar, 1); 5959 if(ip != NULL) { 5960 u.u_error = EEXIST; 5961 goto out; 5962 } 5963 } 5964 if(u.u_error) 5965 return; 5966 ip = maknode(u.u_arg[1]); 5967 if (ip==NULL) 5968 return; 5969 ip->i_addr[0] = u.u_arg[2]; 5970 5971 out: 5972 iput(ip); 5973 } 5974 /* ------------------------ */ 5975 5976 /* sleep system call 5977 * not to be confused with the sleep internal routine. 5978 */ 5979 sslep() 5980 { 5981 char *d[2]; 5982 5983 spl7(); 5984 d[0] = time[0]; 5985 d[1] = time[1]; 5986 dpadd(d, u.u_ar0[R0]); 5987 5988 while(dpcmp(d[0], d[1], time[0], time[1]) > 0) { 5989 if(dpcmp(tout[0], tout[1], time[0], time[1]) <= 0 || 5990 dpcmp(tout[0], tout[1], d[0], d[1]) > 0) { 5991 tout[0] = d[0]; 5992 tout[1] = d[1]; 5993 } 5994 sleep(tout, PSLEP); 5995 } 5996 spl0(); 5997 } 5998 /* ------------------------ */ 5999