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