diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-01-04 16:03:48 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-01-04 16:03:48 +0000 |
commit | 78c388aed2b7184182c08428db1de6c872d815f5 (patch) | |
tree | 4b2003b1b4ceb241a17faa995da8dd1004bb8e45 /fs/pipe.c | |
parent | eb7a5bf93aaa4be1d7c6181100ab7639e74d67f7 (diff) |
Merge with Linux 2.1.131 and more MIPS goodies.
(Did I mention that CVS is buggy ...)
Diffstat (limited to 'fs/pipe.c')
-rw-r--r-- | fs/pipe.c | 33 |
1 files changed, 20 insertions, 13 deletions
@@ -4,12 +4,6 @@ * Copyright (C) 1991, 1992 Linus Torvalds */ -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/signal.h> -#include <linux/fcntl.h> -#include <linux/termios.h> #include <linux/mm.h> #include <linux/file.h> #include <linux/poll.h> @@ -92,7 +86,7 @@ static ssize_t pipe_write(struct file * filp, const char * buf, size_t count, loff_t *ppos) { struct inode * inode = filp->f_dentry->d_inode; - ssize_t chars = 0, free = 0, written = 0; + ssize_t chars = 0, free = 0, written = 0, err=0; char *pipebuf; if (ppos != &filp->f_pos) @@ -107,16 +101,26 @@ static ssize_t pipe_write(struct file * filp, const char * buf, free = count; else free = 1; /* can't do it atomically, wait for any free space */ + up(&inode->i_sem); + if (down_interruptible(&inode->i_atomic_write)) { + down(&inode->i_sem); + return -ERESTARTSYS; + } while (count>0) { while ((PIPE_FREE(*inode) < free) || PIPE_LOCK(*inode)) { if (!PIPE_READERS(*inode)) { /* no readers */ send_sig(SIGPIPE,current,0); - return written? :-EPIPE; + err = -EPIPE; + goto errout; + } + if (signal_pending(current)) { + err = -ERESTARTSYS; + goto errout; + } + if (filp->f_flags & O_NONBLOCK) { + err = -EAGAIN; + goto errout; } - if (signal_pending(current)) - return written? :-ERESTARTSYS; - if (filp->f_flags & O_NONBLOCK) - return written? :-EAGAIN; interruptible_sleep_on(&PIPE_WAIT(*inode)); } PIPE_LOCK(*inode)++; @@ -139,7 +143,10 @@ static ssize_t pipe_write(struct file * filp, const char * buf, } inode->i_ctime = inode->i_mtime = CURRENT_TIME; mark_inode_dirty(inode); - return written; +errout: + up(&inode->i_atomic_write); + down(&inode->i_sem); + return written ? written : err; } static long long pipe_lseek(struct file * file, long long offset, int orig) |