# /* * Copyright 1973 Bell Telephone Laboratories Inc */ #include "../param.h" #include "../systm.h" #include "../user.h" #include "../inode.h" #include "../file.h" #include "../reg.h" #define PIPSIZ 4096 pipe() { register *ip, *rf, *wf; ip = ialloc(rootdev); if(ip == NULL) return; wf = falloc(); if(wf == NULL) { iput(ip); return; } u.u_ar0[R1] = u.u_ar0[R0]; rf = falloc(); if(rf == NULL) { wf->f_count = 0; u.u_ofile[u.u_ar0[R1]] = NULL; iput(ip); return; } wf->f_flag = FWRITE|FPIPE; wf->f_inode = ip; rf->f_flag = FREAD|FPIPE; rf->f_inode = ip; ip->i_count = 2; ip->i_flag = IACC|IUPD; ip->i_mode = IALLOC; } readp(fp) int *fp; { register *rp, *ip; rp = fp; ip = rp->f_inode; loop: plock(ip); if(rp->f_offset[1] == ip->i_size1) { if(rp->f_offset[1] != 0) { rp->f_offset[1] = 0; ip->i_size1 = 0; if(ip->i_mode&IWRITE) { ip->i_mode =& ~IWRITE; wakeup(ip+1); } } prele(ip); if(ip->i_count < 2) return; ip->i_mode =| IREAD; sleep(ip+2, PPIPE); goto loop; } u.u_offset[0] = 0; u.u_offset[1] = rp->f_offset[1]; readi(ip); rp->f_offset[1] = u.u_offset[1]; prele(ip); } writep(fp) { register *rp, *ip, c; rp = fp; ip = rp->f_inode; c = u.u_count; loop: plock(ip); if(ip->i_count<2 || c==0) { prele(ip); u.u_count = c; return; } if(ip->i_size1 == PIPSIZ) { ip->i_mode =| IWRITE; prele(ip); sleep(ip+1, PPIPE); goto loop; } u.u_offset[0] = 0; u.u_offset[1] = ip->i_size1; u.u_count = min(c, PIPSIZ-u.u_offset[1]); c =- u.u_count; writei(ip); prele(ip); if(ip->i_mode&IREAD) { ip->i_mode =& ~IREAD; wakeup(ip+2); } goto loop; } plock(ip) int *ip; { register *rp; rp = ip; while(rp->i_flag&ILOCK) { rp->i_flag =| IWANT; sleep(rp, PPIPE); } rp->i_flag =| ILOCK; } prele(ip) int *ip; { register *rp; rp = ip; rp->i_flag =& ~ILOCK; if(rp->i_flag&IWANT) { rp->i_flag =& ~IWANT; wakeup(rp); } }