09050 #include "../h/param.h" 09051 #include "../h/systm.h" 09052 #include "../h/dir.h" 09053 #include "../h/user.h" 09054 #include "../h/inode.h" 09055 #include "../h/file.h" 09056 #include "../h/reg.h" 09057 09058 /* 09059 * Max allowable buffering per pipe. 09060 * This is also the max size of the 09061 * file created to implement the pipe. 09062 * If this size is bigger than 5120, 09063 * pipes will be implemented with large 09064 * files, which is probably not good. 09065 */ 09066 #define PIPSIZ 4096 09067 09068 /* 09069 * The sys-pipe entry. 09070 * Allocate an inode on the root device. 09071 * Allocate 2 file structures. 09072 * Put it all together with flags. 09073 */ 09074 pipe() 09075 { 09076 register struct inode *ip; 09077 register struct file *rf, *wf; 09078 int r; 09079 09080 ip = ialloc(pipedev); 09081 if(ip == NULL) 09082 return; 09083 rf = falloc(); 09084 if(rf == NULL) { 09085 iput(ip); 09086 return; 09087 } 09088 r = u.u_r.r_val1; 09089 wf = falloc(); 09090 if(wf == NULL) { 09091 rf->f_count = 0; 09092 u.u_ofile[r] = NULL; 09093 iput(ip); 09094 return; 09095 } 09096 u.u_r.r_val2 = u.u_r.r_val1; 09097 u.u_r.r_val1 = r; 09098 wf->f_flag = FWRITE|FPIPE; 09099 wf->f_inode = ip; 09100 rf->f_flag = FREAD|FPIPE; 09101 rf->f_inode = ip; 09102 ip->i_count = 2; 09103 ip->i_mode = IFREG; 09104 ip->i_flag = IACC|IUPD|ICHG; 09105 } 09106 09107 /* 09108 * Read call directed to a pipe. 09109 */ 09110 readp(fp) 09111 register struct file *fp; 09112 { 09113 register struct inode *ip; 09114 09115 ip = fp->f_inode; 09116 09117 loop: 09118 /* 09119 * Very conservative locking. 09120 */ 09121 09122 plock(ip); 09123 /* 09124 * If nothing in the pipe, wait. 09125 */ 09126 if (ip->i_size == 0) { 09127 /* 09128 * If there are not both reader and 09129 * writer active, return without 09130 * satisfying read. 09131 */ 09132 prele(ip); 09133 if(ip->i_count < 2) 09134 return; 09135 ip->i_mode |= IREAD; 09136 sleep((caddr_t)ip+2, PPIPE); 09137 goto loop; 09138 } 09139 09140 /* 09141 * Read and return 09142 */ 09143 09144 u.u_offset = fp->f_un.f_offset; 09145 readi(ip); 09146 fp->f_un.f_offset = u.u_offset; 09147 /* 09148 * If reader has caught up with writer, reset 09149 * offset and size to 0. 09150 */ 09151 if (fp->f_un.f_offset == ip->i_size) { 09152 fp->f_un.f_offset = 0; 09153 ip->i_size = 0; 09154 if(ip->i_mode & IWRITE) { 09155 ip->i_mode &= ~IWRITE; 09156 wakeup((caddr_t)ip+1); 09157 } 09158 } 09159 prele(ip); 09160 } 09161 09162 /* 09163 * Write call directed to a pipe. 09164 */ 09165 writep(fp) 09166 register struct file *fp; 09167 { 09168 register c; 09169 register struct inode *ip; 09170 09171 ip = fp->f_inode; 09172 c = u.u_count; 09173 09174 loop: 09175 09176 /* 09177 * If all done, return. 09178 */ 09179 09180 plock(ip); 09181 if(c == 0) { 09182 prele(ip); 09183 u.u_count = 0; 09184 return; 09185 } 09186 09187 /* 09188 * If there are not both read and 09189 * write sides of the pipe active, 09190 * return error and signal too. 09191 */ 09192 09193 if(ip->i_count < 2) { 09194 prele(ip); 09195 u.u_error = EPIPE; 09196 psignal(u.u_procp, SIGPIPE); 09197 return; 09198 } 09199 09200 /* 09201 * If the pipe is full, 09202 * wait for reads to deplete 09203 * and truncate it. 09204 */ 09205 09206 if(ip->i_size >= PIPSIZ) { 09207 ip->i_mode |= IWRITE; 09208 prele(ip); 09209 sleep((caddr_t)ip+1, PPIPE); 09210 goto loop; 09211 } 09212 09213 /* 09214 * Write what is possible and 09215 * loop back. 09216 * If writing less than PIPSIZ, it always goes. 09217 * One can therefore get a file > PIPSIZ if write 09218 * sizes do not divide PIPSIZ. 09219 */ 09220 09221 u.u_offset = ip->i_size; 09222 u.u_count = min((unsigned)c, (unsigned)PIPSIZ); 09223 c -= u.u_count; 09224 writei(ip); 09225 prele(ip); 09226 if(ip->i_mode&IREAD) { 09227 ip->i_mode &= ~IREAD; 09228 wakeup((caddr_t)ip+2); 09229 } 09230 goto loop; 09231 } 09232 09233 /* 09234 * Lock a pipe. 09235 * If its already locked, 09236 * set the WANT bit and sleep. 09237 */ 09238 plock(ip) 09239 register struct inode *ip; 09240 { 09241 09242 while(ip->i_flag&ILOCK) { 09243 ip->i_flag |= IWANT; 09244 sleep((caddr_t)ip, PINOD); 09245 } 09246 ip->i_flag |= ILOCK; 09247 } 09248 09249 /* 09250 * Unlock a pipe. 09251 * If WANT bit is on, 09252 * wakeup. 09253 * This routine is also used 09254 * to unlock inodes in general. 09255 */ 09256 prele(ip) 09257 register struct inode *ip; 09258 { 09259 09260 ip->i_flag &= ~ILOCK; 09261 if(ip->i_flag&IWANT) { 09262 ip->i_flag &= ~IWANT; 09263 wakeup((caddr_t)ip); 09264 } 09265 } 09266 09267 09268 09269 09270 09271 09272 09273 09274 09275 09276 09277 09278 09279 09280 09281 09282 09283 09284 09285 09286 09287 09288 09289 09290 09291 09292 09293 09294 09295 09296 09297 09298 09299