1 #include "types.h" 2 #include "param.h" 3 #include "x86.h" 4 #include "mmu.h" 5 #include "proc.h" 6 #include "defs.h" 7 #include "fd.h" 8 9 #define PIPESIZE 512 10 11 struct pipe { 12 int readopen; // read fd is still open 13 int writeopen; // write fd is still open 14 int writep; // next index to write 15 int readp; // next index to read 16 char data[PIPESIZE]; 17 }; 18 19 int 20 pipe_alloc(struct fd **fd1, struct fd **fd2) 21 { 22 *fd1 = *fd2 = 0; 23 struct pipe *p = 0; 24 25 if((*fd1 = fd_alloc()) == 0) 26 goto oops; 27 if((*fd2 = fd_alloc()) == 0) 28 goto oops; 29 if((p = (struct pipe *) kalloc(PAGE)) == 0) 30 goto oops; 31 (*fd1)->type = FD_PIPE; 32 (*fd1)->readable = 1; 33 (*fd1)->writeable = 0; 34 (*fd1)->pipe = p; 35 (*fd2)->type = FD_PIPE; 36 (*fd2)->readable = 0; 37 (*fd2)->writeable = 1; 38 (*fd2)->pipe = p; 39 return 0; 40 oops: 41 if(p) 42 kfree((char *) p, PAGE); 43 if(*fd1){ 44 (*fd1)->type = FD_NONE; 45 fd_close(*fd1); 46 } 47 if(*fd2){ 48 (*fd2)->type = FD_NONE; 49 fd_close(*fd2); 50 } 51 return -1; 52 } 53 54 void 55 pipe_close(struct pipe *p, int writeable) 56 { 57 if(writeable) 58 p->writeopen = 0; 59 else 60 p->readopen = 0; 61 if(p->readopen == 0 && p->writeopen == 0) 62 kfree((char *) p, PAGE); 63 } 64 65 int 66 pipe_write(struct pipe *p, char *addr, int n) 67 { 68 int i; 69 70 for(i = 0; i < n; i++){ 71 while(((p->writep + 1) % PIPESIZE) == p->readp){ 72 if(p->readopen == 0) 73 return -1; 74 sleep(&p->writep); 75 } 76 p->data[p->writep] = addr[i]; 77 p->writep = (p->writep + 1) % PIPESIZE; 78 } 79 return i; 80 } 81 82 int 83 pipe_read(struct pipe *p, char *addr, int n) 84 { 85 int i; 86 87 while(p->readp == p->writep){ 88 if(p->writeopen == 0) 89 return 0; 90 sleep(&p->readp); 91 } 92 93 for(i = 0; i < n; i++){ 94 if(p->readp == p->writep) 95 break; 96 addr[i] = p->data[p->readp]; 97 p->readp = (p->readp + 1) % PIPESIZE; 98 } 99 return i; 100 } 101