1c41f1de5Srtm #include "types.h" 2558ab49fSrsc #include "defs.h" 3c41f1de5Srtm #include "param.h" 4c41f1de5Srtm #include "mmu.h" 5c41f1de5Srtm #include "proc.h" 60aef8914SRuss Cox #include "fs.h" 71ddfbbb1SFrans Kaashoek #include "spinlock.h" 8*dec637bcSFrans Kaashoek #include "sleeplock.h" 9*dec637bcSFrans Kaashoek #include "file.h" 10c41f1de5Srtm 11c41f1de5Srtm #define PIPESIZE 512 12c41f1de5Srtm 13c41f1de5Srtm struct pipe { 144e8f237bSrtm struct spinlock lock; 15c41f1de5Srtm char data[PIPESIZE]; 1600e57115SRuss Cox uint nread; // number of bytes read 1700e57115SRuss Cox uint nwrite; // number of bytes written 1800e57115SRuss Cox int readopen; // read fd is still open 1900e57115SRuss Cox int writeopen; // write fd is still open 20c41f1de5Srtm }; 21c41f1de5Srtm 22c41f1de5Srtm int 237834cca6Srsc pipealloc(struct file **f0, struct file **f1) 24c41f1de5Srtm { 253bbbaca1Srsc struct pipe *p; 26c41f1de5Srtm 273bbbaca1Srsc p = 0; 283bbbaca1Srsc *f0 = *f1 = 0; 293ce16470Srsc if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0) 303ce16470Srsc goto bad; 317d7dc933SRobert Morris if((p = (struct pipe*)kalloc()) == 0) 323ce16470Srsc goto bad; 338b4e2a08Srtm p->readopen = 1; 348b4e2a08Srtm p->writeopen = 1; 3500e57115SRuss Cox p->nwrite = 0; 3600e57115SRuss Cox p->nread = 0; 375be0039cSrtm initlock(&p->lock, "pipe"); 382cbb4b18Srsc (*f0)->type = FD_PIPE; 392cbb4b18Srsc (*f0)->readable = 1; 402cbb4b18Srsc (*f0)->writable = 0; 412cbb4b18Srsc (*f0)->pipe = p; 422cbb4b18Srsc (*f1)->type = FD_PIPE; 432cbb4b18Srsc (*f1)->readable = 0; 442cbb4b18Srsc (*f1)->writable = 1; 452cbb4b18Srsc (*f1)->pipe = p; 46c41f1de5Srtm return 0; 47f1f8dd91Srsc 486eed1ee9Srsc //PAGEBREAK: 20 493ce16470Srsc bad: 50c41f1de5Srtm if(p) 517d7dc933SRobert Morris kfree((char*)p); 52f3685aa3Srsc if(*f0) 532cbb4b18Srsc fileclose(*f0); 54f3685aa3Srsc if(*f1) 552cbb4b18Srsc fileclose(*f1); 56c41f1de5Srtm return -1; 57c41f1de5Srtm } 58c41f1de5Srtm 59c41f1de5Srtm void 607834cca6Srsc pipeclose(struct pipe *p, int writable) 61c41f1de5Srtm { 62bd228a81Srtm acquire(&p->lock); 63d4c64e5dSrsc if(writable){ 64c41f1de5Srtm p->writeopen = 0; 6500e57115SRuss Cox wakeup(&p->nread); 668b4e2a08Srtm } else { 67c41f1de5Srtm p->readopen = 0; 6800e57115SRuss Cox wakeup(&p->nwrite); 698b4e2a08Srtm } 70e670a483Skolya if(p->readopen == 0 && p->writeopen == 0){ 71bd228a81Srtm release(&p->lock); 727d7dc933SRobert Morris kfree((char*)p); 73e670a483Skolya } else 74e670a483Skolya release(&p->lock); 75c41f1de5Srtm } 76c41f1de5Srtm 770aef8914SRuss Cox //PAGEBREAK: 40 78c41f1de5Srtm int 797834cca6Srsc pipewrite(struct pipe *p, char *addr, int n) 80c41f1de5Srtm { 81c41f1de5Srtm int i; 82c41f1de5Srtm 834e8f237bSrtm acquire(&p->lock); 84c41f1de5Srtm for(i = 0; i < n; i++){ 8500e57115SRuss Cox while(p->nwrite == p->nread + PIPESIZE){ //DOC: pipewrite-full 8648755214SRuss Cox if(p->readopen == 0 || proc->killed){ 874e8f237bSrtm release(&p->lock); 8846bbd72fSrtm return -1; 8946bbd72fSrtm } 9000e57115SRuss Cox wakeup(&p->nread); 9100e57115SRuss Cox sleep(&p->nwrite, &p->lock); //DOC: pipewrite-sleep 92c41f1de5Srtm } 9300e57115SRuss Cox p->data[p->nwrite++ % PIPESIZE] = addr[i]; 94c41f1de5Srtm } 9500e57115SRuss Cox wakeup(&p->nread); //DOC: pipewrite-wakeup1 96ea6e3709Srsc release(&p->lock); 9700e57115SRuss Cox return n; 98c41f1de5Srtm } 99c41f1de5Srtm 100c41f1de5Srtm int 1017834cca6Srsc piperead(struct pipe *p, char *addr, int n) 102c41f1de5Srtm { 103c41f1de5Srtm int i; 104c41f1de5Srtm 10546bbd72fSrtm acquire(&p->lock); 10600e57115SRuss Cox while(p->nread == p->nwrite && p->writeopen){ //DOC: pipe-empty 10748755214SRuss Cox if(proc->killed){ 10846bbd72fSrtm release(&p->lock); 1093ce16470Srsc return -1; 11046bbd72fSrtm } 11100e57115SRuss Cox sleep(&p->nread, &p->lock); //DOC: piperead-sleep 112c41f1de5Srtm } 11300e57115SRuss Cox for(i = 0; i < n; i++){ //DOC: piperead-copy 11400e57115SRuss Cox if(p->nread == p->nwrite) 115c41f1de5Srtm break; 11600e57115SRuss Cox addr[i] = p->data[p->nread++ % PIPESIZE]; 117c41f1de5Srtm } 11800e57115SRuss Cox wakeup(&p->nwrite); //DOC: piperead-wakeup 119ea6e3709Srsc release(&p->lock); 120c41f1de5Srtm return i; 121c41f1de5Srtm } 122