Linux 2.3.3[234] FIFOs (named pipes) are unreliable [corrected patch]

Markus Schoder (markus.schoder@inetmail.de)
Thu, 23 Dec 1999 03:36:29 +0100 (MET)


The patch in my previous mail contained a bug (which indirectly caused the
double posting because my MDA (qmail) seemed not to work anymore).

Here is the corrected patch.

--
Markus

--- /tmp/linux/fs/fifo.c Wed Dec 15 13:18:28 1999 +++ linux/fs/fifo.c Thu Dec 23 03:07:46 1999 @@ -41,6 +41,7 @@ PIPE_BASE(*inode) = (char *) page; PIPE_START(*inode) = PIPE_LEN(*inode) = 0; PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0; + PIPE_CONNECT(*inode) = 0; } switch (filp->f_mode) { @@ -51,11 +52,13 @@ * opened, even when there is no process writing the FIFO. */ filp->f_op = &connecting_fifo_fops; - if (PIPE_READERS(*inode)++ == 0) + if (PIPE_READERS(*inode)++ == 0 && PIPE_WRITERS(*inode)) { + PIPE_CONNECT(*inode) = 1; wake_up_interruptible(PIPE_WAIT(*inode)); + } if (!(filp->f_flags & O_NONBLOCK)) { - while (!PIPE_WRITERS(*inode)) { + while (!PIPE_CONNECT(*inode)) { if (signal_pending(current)) goto err_rd; up(PIPE_SEM(*inode)); @@ -69,7 +72,7 @@ } } - if (PIPE_WRITERS(*inode)) + if (PIPE_CONNECT(*inode)) filp->f_op = &read_fifo_fops; break; @@ -80,14 +83,17 @@ * errno=ENXIO when there is no process reading the FIFO. */ ret = -ENXIO; - if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode)) + if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode) && + !PIPE_CONNECT(*inode)) goto err; filp->f_op = &write_fifo_fops; - if (!PIPE_WRITERS(*inode)++) + if (!PIPE_WRITERS(*inode)++ && PIPE_READERS(*inode)) { + PIPE_CONNECT(*inode) = 1; wake_up_interruptible(PIPE_WAIT(*inode)); + } - while (!PIPE_READERS(*inode)) { + while (!PIPE_CONNECT(*inode)) { if (signal_pending(current)) goto err_wr; up(PIPE_SEM(*inode)); @@ -107,8 +113,10 @@ PIPE_READERS(*inode)++; PIPE_WRITERS(*inode)++; - if (PIPE_READERS(*inode) == 1 || PIPE_WRITERS(*inode) == 1) + if (PIPE_READERS(*inode) == 1 || PIPE_WRITERS(*inode) == 1) { + PIPE_CONNECT(*inode) = 1; wake_up_interruptible(PIPE_WAIT(*inode)); + } break; default: --- /tmp/linux/include/linux/pipe_fs_i.h Wed Dec 15 13:18:18 1999 +++ linux/include/linux/pipe_fs_i.h Thu Dec 23 01:43:02 1999 @@ -9,6 +9,7 @@ unsigned int writers; unsigned int waiting_readers; unsigned int waiting_writers; + unsigned int connect; }; /* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual @@ -24,6 +25,7 @@ #define PIPE_WRITERS(inode) ((inode).i_pipe->writers) #define PIPE_WAITING_READERS(inode) ((inode).i_pipe->waiting_readers) #define PIPE_WAITING_WRITERS(inode) ((inode).i_pipe->waiting_writers) +#define PIPE_CONNECT(inode) ((inode).i_pipe->connect) #define PIPE_EMPTY(inode) (PIPE_LEN(inode) == 0) #define PIPE_FULL(inode) (PIPE_LEN(inode) == PIPE_SIZE)

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/