summaryrefslogtreecommitdiffstats
path: root/fs/pipe.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-01-04 16:03:48 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-01-04 16:03:48 +0000
commit78c388aed2b7184182c08428db1de6c872d815f5 (patch)
tree4b2003b1b4ceb241a17faa995da8dd1004bb8e45 /fs/pipe.c
parenteb7a5bf93aaa4be1d7c6181100ab7639e74d67f7 (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.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/fs/pipe.c b/fs/pipe.c
index 8308eb06c..999013ef8 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -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)