diff --git a/ChangeLog b/ChangeLog
index fc33a6d812382e80caca0d6ce8a7e36ce81d278d..8f6313bce837ce6aaa38de8644cabaa3927092fe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -376,4 +376,5 @@
 	* Correct bug in recursive mutex logic
 	* Add mkfifo()
 	* Add pipe() and test for both pipes and fifos
+	* Attempts to open a FIFO will now block until there is at least one writer
 
diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html
index 70b781c8ede2f77943d5f68cae63a5b1c6e2dc4f..5d3c130bcd6dfed5bf40de88608dd3e58b7bf893 100644
--- a/Documentation/NuttX.html
+++ b/Documentation/NuttX.html
@@ -1025,6 +1025,7 @@ nuttx-0.3.12 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
 	* Correct bug in recursive mutex logic
 	* Add mkfifo()
 	* Add pipe() and test for both pipes and fifos
+	* Attempts to open a FIFO will now block until there is at least one writer
 
 pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
 
diff --git a/drivers/fifo.c b/drivers/fifo.c
index 88ab1deb60f61fdbeb465cd29390eed750876f1f..9ad64dbcb2ebf25aba2f450a49c44a61b4fbfbfa 100644
--- a/drivers/fifo.c
+++ b/drivers/fifo.c
@@ -96,8 +96,12 @@ static struct file_operations fifo_fops =
  *   Once the FIFO has been created by mkfifo(), any thread can open it for
  *   reading or writing, in the same way as an ordinary file. However, it must
  *   have been opened from both reading and writing before input or output
- *   can be performed.  Unlike other mkfifo() implementations, this one will
- *   NOT block when the FIFO is opened on only one end.
+ *   can be performed.  This FIFO implementation will block all attempts to
+ *   open a FIFO read-only until at least one thread has opened the FIFO for
+ *   writing.
+ *
+ *   If all threads that write to the FIFO have closed, subsequent calls to
+ *   read() on the FIFO will return 0 (end-of-file).
  *
  * Inputs:
  *   pathname - The full path to the FIFO instance to attach to or to create
diff --git a/drivers/pipe-common.c b/drivers/pipe-common.c
index 1004d15f876d767eb133f82e17dea389e8783683..ab6b7d3808ca91f1da8afb7c03b814e554d1e831 100644
--- a/drivers/pipe-common.c
+++ b/drivers/pipe-common.c
@@ -139,6 +139,7 @@ int pipecommon_open(FAR struct file *filep)
 {
   struct inode      *inode = filep->f_inode;
   struct pipe_dev_s *dev   = inode->i_private;
+  int                sval;
  
   /* Some sanity checking */
 #if CONFIG_DEBUG
@@ -160,11 +161,37 @@ int pipecommon_open(FAR struct file *filep)
       if ((filep->f_oflags & O_WROK) != 0)
         {
           dev->s.d_nwriters++;
+
+          /* If this this is the first writer, then the read semaphore indicates the
+           * number of readers waiting for the first writer.  Wake them all up.
+           */
+          if (dev->s.d_nwriters == 1)
+            {
+              while (sem_getvalue(&dev->s.d_rdsem, &sval) == 0 && sval < 0)
+                {
+                  sem_post(&dev->s.d_rdsem);
+                }
+            }
         }
 
       /* If opened for read-only, then wait for at least one writer on the pipe */
 
+      sched_lock();
       (void)sem_post(&dev->s.d_bfsem);
+      if ((filep->f_oflags & O_RDWR) != O_RDONLY && dev->s.d_nwriters < 1)
+        {
+          /* NOTE: d_rdsem is normally used when the read logic waits for more
+           * data to be written.  But until the first writer has opened the
+           * pipe, the meaning is different: it is used prevent O_RDONLY open
+           * calls from returning until there is at least one writer on the pipe.
+           * This is required both by spec and also because it prevents
+           * subsequent read() calls from returning end-of-file because there is
+           * no writer on the pipe.
+           */
+
+          pipecommon_semtake(&dev->s.d_rdsem);
+        }
+      sched_unlock();
       return OK;
   }
   return ERROR;
diff --git a/examples/pipe/pipe_main.c b/examples/pipe/pipe_main.c
index 5b3874171454fb022a0d108e98e8d3b20c8abe5a..eadad056292a264cfe749ad657e4ba189a1d101f 100644
--- a/examples/pipe/pipe_main.c
+++ b/examples/pipe/pipe_main.c
@@ -127,7 +127,7 @@ static void *reader(pthread_addr_t pvarg)
       if (nbytes > NREAD_BYTES)
         {
           fprintf(stderr, "reader: Too many bytes read -- aborting: %d\n", nbytes);
-          return (void*)3;
+          return (void*)4;
         }
     }
   printf("reader: %d bytes read\n", nbytes);