summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/pipe.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/kernel/pipe.c b/kernel/pipe.c
index 7ed402d..b6eefb9 100644
--- a/kernel/pipe.c
+++ b/kernel/pipe.c
@@ -76,26 +76,29 @@ pipeclose(struct pipe *pi, int writable)
int
pipewrite(struct pipe *pi, uint64 addr, int n)
{
- int i;
- char ch;
+ int i = 0;
struct proc *pr = myproc();
acquire(&pi->lock);
- for(i = 0; i < n; i++){
- while(pi->nwrite == pi->nread + PIPESIZE){ //DOC: pipewrite-full
- if(pi->readopen == 0 || pr->killed){
- release(&pi->lock);
- return -1;
- }
+ while(i < n){
+ if(pi->readopen == 0 || pr->killed){
+ release(&pi->lock);
+ return -1;
+ }
+ if(pi->nwrite == pi->nread + PIPESIZE){ //DOC: pipewrite-full
wakeup(&pi->nread);
sleep(&pi->nwrite, &pi->lock);
+ } else {
+ char ch;
+ if(copyin(pr->pagetable, &ch, addr + i, 1) == -1)
+ break;
+ pi->data[pi->nwrite++ % PIPESIZE] = ch;
+ i++;
}
- if(copyin(pr->pagetable, &ch, addr + i, 1) == -1)
- break;
- pi->data[pi->nwrite++ % PIPESIZE] = ch;
}
wakeup(&pi->nread);
release(&pi->lock);
+
return i;
}