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: /* ---------------------------       */