int write_pipe(int fd, char *buf, int n) { // your code for write_pipe() PIPE *pipe; char * offset; int wbytes = 0; u8 byte; offset = buf; pipe = running->fd[fd]->pipe_ptr; if(running->fd[fd] ==0){ printf("Error: fd is not open\n"); return -1; } if(running->fd[fd]->mode != WRITE_PIPE){ printf("Error: fd mode is not write\n"); return -2; } printf("BEFORE WRITE:\n"); show_pipe(pipe); while(wbytes < n){ if(pipe->nreader == 0){ printf("NO READER\n"); return BROKEN_PIPE_ERROR; }else{ if(pipe->room != 0){ byte = get_byte(running->uss, offset); printf("WRITE BYTE: %c[%d]\n", byte, pipe->head); pipe->buf[pipe->head] = byte; pipe->head++; offset++; wbytes++; pipe->room--; pipe->data++; pipe->head %= PIPE_SIZE; kwakeup(&(pipe->data)); }else{ kwakeup(&(pipe->data)); ksleep(&(pipe->room)); } } } printf("AFTER WRITE:\n"); show_pipe(pipe); return wbytes; }
int read_pipe(int fd, char *buf, int n) { int r = 0; char c; OFT *op; PIPE *p; if (n<=0) return 0; if (fd < 0 || fd > NFD || running->fd[fd] == 0){ printf("bad fd %d\n", fd); return -1; } op = running->fd[fd]; if (op->mode != READ_PIPE){ printf("fd = %d is NOT for read\n", fd); return -1; } p = op->pipe_ptr; printf("pipe before reading\n"); show_pipe(p); while(n){ while(p->data){ c = p->buf[p->tail++]; put_byte(c, running->uss, buf); p->tail %= PSIZE; p->data--; p->room++; n--; r++; buf++; if (n == 0) break; } if (n==0 || r){ kwakeup(&p->room); printf("pipe after reading\n"); show_pipe(p); return r; } // pipe has no data if (p->nwriter){ // if pipe still has writer printf("pipe before reader goes to sleep\n"); show_pipe(p); kwakeup(&p->room); // wakeup ALL writers, if any. ksleep(&p->data); // sleep for data continue; } // pipe has no writer and no data return 0; } }
int write_pipe(int fd, char *buf, int n) { char c; int r=0; PIPE *p; OFT *op; if (fd < 0 || fd > NFD || running->fd[fd] == 0){ printf("bad fd %d\n", fd); return -1; } op = running->fd[fd]; if (op->mode != WRITE_PIPE){ printf("fd = %d is NOT for write\n", fd); return -1; } p = op->pipe_ptr; printf("pipe before writing\n"); show_pipe(p); while(n){ if (!p->nreader){ // no more readers printf("proc %d : BROKEN_PIPE error\n", running->pid); kexit(0x0D); // simulate SIGPIPE=13 } while(p->room && n){ p->buf[p->head++] = get_byte(running->uss, buf); p->head %= PSIZE; p->data++; p->room--; n--; r++; buf++; } kwakeup(&p->data); // wakeup ALL readers, if any. if (n==0){ printf("pipe after writing\n"); show_pipe(p); return r; // finished writing n bytes } // still has data to write but pipe has no room printf("pipe before writer goes to sleep\n"); show_pipe(p); ksleep(&p->room); // sleep for room } return r; }
int read_pipe(int fd, char *buf, int n) { // your code for read_pipe() PIPE *pipe; char * offset; int rbytes = 0; u8 byte; offset = buf; pipe = running->fd[fd]->pipe_ptr; if(running->fd[fd] ==0){ printf("Error: fd is not open\n"); return -1; } if(running->fd[fd]->mode != READ_PIPE){ printf("Error: fd mode is not read\n"); return -2; } printf("BEFORE READ:\n"); show_pipe(pipe); while(rbytes < n){ if(pipe->nwriter == 0){ /* read as much as it can; either nbytes or until no more data. return ACTUAL number of bytes read. */ // Put the byte into umode, then destroy it in the pipe printf("NO WRITER\n"); if(pipe->data != 0){ byte = pipe->buf[pipe->tail]; printf("READ BYTE: %c[%d]\n", byte, pipe->tail); put_byte(byte, running->uss, offset); pipe->buf[pipe->tail] = 0; pipe->room++; pipe->data--; rbytes++; offset++; pipe->tail++; pipe->tail %= PIPE_SIZE; }else{ printf("AFTER READ:\n"); show_pipe(pipe); return rbytes; } // ksleep(&(pipe->data)); }else{ if(pipe->data != 0){ byte = pipe->buf[pipe->tail]; printf("READ BYTE: %c[%d]\n", byte, pipe->tail); put_byte(byte, running->uss, offset); pipe->buf[pipe->tail] = 0; pipe->room++; pipe->data--; rbytes++; offset++; pipe->tail++; pipe->tail %= PIPE_SIZE; kwakeup(&(pipe->room)); }else{ kwakeup(&(pipe->room)); ksleep(&(pipe->data)); } } } printf("AFTER READ:\n"); show_pipe(pipe); return rbytes; }
int kwrite_pipe(int fd, char *buf, int n){ char c; int r = 0; PIPE *pp; OFT* op; printf("Attempt pipe write of %d bytes to fd (%d)\n", n, fd); // if(n <= 0){ // return 0; // } if(fd >= NFD || fd < 0){ printf("invalid file descriptor (out of bounds).\n"); return -1; } if(!running->fd[fd]){ printf("invalid file descriptor (not opened).\n"); return -1; } op = running->fd[fd]; pp = op->pipe_ptr; if(op->mode != WRITE_PIPE){ printf("fd (%d) is not for pipe read\n", fd); return -1; } printf("pipe before writing\n"); show_pipe(pp); while(n){ if(!pp->nreader){ printf("proc %d : BROKEN_PIPE error\n", running->pid); kexit(0x0D); } while(pp->room && n){ pp->buf[pp->head++] = get_byte(running->uss, buf); pp->head = pp->head % PSIZE; pp->data++; pp->room--; n--; r++; buf++; } kwakeup(&(pp->data)); if(n==0){ printf("pipe after writing\n"); show_pipe(pp); return r; } printf("pipe before writer goes to sleep\n"); show_pipe(pp); ksleep(&(pp->room)); } return r; }
int kread_pipe(int fd, char *buf, int n){ int r = 0; OFT *op; PIPE *pp; char c; printf("Attempted to read %d bytes from fd (%d)\n", n, fd); if(n <= 0){ return 0; } if(fd >= NFD || fd < 0){ printf("invalid file descriptor (out of bounds).\n"); return -1; } if(!running->fd[fd]){ printf("invalid file descriptor (not opened).\n"); return -1; } op = running->fd[fd]; pp = op->pipe_ptr; if(op->mode != READ_PIPE){ printf("fd (%d) is not for pipe read\n", fd); return -1; } printf("pipe before reading\n"); show_pipe(pp); while(n){ while(pp->data){ c = pp->buf[(pp->tail)++]; put_byte(c, running->uss, buf); pp->tail = pp->tail % PSIZE; pp->data--; pp->room++; n--; r++; buf++; if(n == 0) break; } if(n == 0 || r){ kwakeup(&(pp->room)); printf("pipe after reading\n"); show_pipe(pp); return r; } //need some but didn't get none if(pp->nwriter){ printf("pipe before reader goes to sleep\n"); show_pipe(pp); kwakeup(&(pp->room)); ksleep(&(pp->data)); continue; } //pipe has no writer and no data printf("pipe had no writer and no data\n"); return 0; } printf("how tf do we get here?\n"); return 0; }