diff --git a/arch/sim/src/up_devconsole.c b/arch/sim/src/up_devconsole.c
index 89eb33c33e92571b9e44460c23c827ba349d929a..551d21600b1d9588f4b9ad3e4451197746775996 100644
--- a/arch/sim/src/up_devconsole.c
+++ b/arch/sim/src/up_devconsole.c
@@ -54,7 +54,8 @@
 static ssize_t devconsole_read(struct file *, char *, size_t);
 static ssize_t devconsole_write(struct file *, const char *, size_t);
 #ifndef CONFIG_DISABLE_POLL
-static int     devconsole_poll(FAR struct file *filep, FAR struct pollfd *fds);
+static int     devconsole_poll(FAR struct file *filep, FAR struct pollfd *fds,
+                               boolean setup);
 #endif
 
 /****************************************************************************
@@ -85,7 +86,8 @@ static ssize_t devconsole_write(struct file *filp, const char *buffer, size_t le
 }
 
 #ifndef CONFIG_DISABLE_POLL
-static int devconsole_poll(FAR struct file *filep, FAR struct pollfd *fds)
+static int devconsole_poll(FAR struct file *filep, FAR struct pollfd *fds,
+                           boolean setup)
 {
   return OK;
 }
diff --git a/drivers/dev_null.c b/drivers/dev_null.c
index a5e7d95cebeb60f19a7902a903ac0da4c0ae1c23..a8a8bb01cb6fbe2a3a064a8a991811fddbe5dd5a 100644
--- a/drivers/dev_null.c
+++ b/drivers/dev_null.c
@@ -56,7 +56,8 @@
 static ssize_t devnull_read(FAR struct file *, FAR char *, size_t);
 static ssize_t devnull_write(FAR struct file *, FAR const char *, size_t);
 #ifndef CONFIG_DISABLE_POLL
-static int     devnull_poll(FAR struct file *filp, FAR struct pollfd *fds);
+static int     devnull_poll(FAR struct file *filp, FAR struct pollfd *fds,
+                            boolean setup);
 #endif
 
 /****************************************************************************
@@ -103,9 +104,10 @@ static ssize_t devnull_write(FAR struct file *filp, FAR const char *buffer, size
  ****************************************************************************/
 
 #ifndef CONFIG_DISABLE_POLL
-static int devnull_poll(FAR struct file *filp, FAR struct pollfd *fds)
+static int devnull_poll(FAR struct file *filp, FAR struct pollfd *fds,
+                        boolean setup)
 {
-  if (fds)
+  if (setup)
     {
       fds->revents |= (fds->events & (POLLIN|POLLOUT));
       if (fds->revents != 0)
diff --git a/drivers/dev_zero.c b/drivers/dev_zero.c
index 08815ace5b7d83062c15698ed306eaaf1664cedf..fff88fd8d8dbec606a0ad859ab9bd610df3457ff 100644
--- a/drivers/dev_zero.c
+++ b/drivers/dev_zero.c
@@ -56,7 +56,8 @@
 static ssize_t devzero_read(FAR struct file *, FAR char *, size_t);
 static ssize_t devzero_write(FAR struct file *, FAR const char *, size_t);
 #ifndef CONFIG_DISABLE_POLL
-static int     devzero_poll(FAR struct file *filp, FAR struct pollfd *fds);
+static int     devzero_poll(FAR struct file *filp, FAR struct pollfd *fds,
+                            boolean setup);
 #endif
 
 /****************************************************************************
@@ -104,9 +105,10 @@ static ssize_t devzero_write(FAR struct file *filp, FAR const char *buffer, size
  ****************************************************************************/
 
 #ifndef CONFIG_DISABLE_POLL
-static int devzero_poll(FAR struct file *filp, FAR struct pollfd *fds)
+static int devzero_poll(FAR struct file *filp, FAR struct pollfd *fds,
+                        boolean setup)
 {
-  if (fds)
+  if (setup)
     {
       fds->revents |= (fds->events & (POLLIN|POLLOUT));
       if (fds->revents != 0)
diff --git a/drivers/pipe_common.c b/drivers/pipe_common.c
index cede17ae12a32b7818fbb213c4fe004512954a74..43450155934c188d9dd26fae58340fb6aec3b607 100644
--- a/drivers/pipe_common.c
+++ b/drivers/pipe_common.c
@@ -197,10 +197,6 @@ int pipecommon_open(FAR struct file *filep)
             }
         }
 
-      /* There is no, file-specific private data (at least not yet) */
-
-      filep->f_priv = NULL;
-
       /* Increment the reference count on the pipe instance */
 
       dev->d_refs++;
@@ -517,58 +513,58 @@ ssize_t pipecommon_write(FAR struct file *filep, FAR const char *buffer, size_t
  ****************************************************************************/
 
 #ifndef CONFIG_DISABLE_POLL
-int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds)
+int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds,
+                    boolean setup)
 {
   FAR struct inode      *inode    = filep->f_inode;
   FAR struct pipe_dev_s *dev      = inode->i_private;
   pollevent_t            eventset;
   pipe_ndx_t             nbytes;
+  int                    ret      = OK;
   int                    i;
 
   /* Some sanity checking */
+
 #if CONFIG_DEBUG
-  if (!dev)
+  if (!dev || !fds)
     {
       return -ENODEV;
     }
 #endif
 
-  /* Find an available slot for the poll structure reference */
+  /* Are we setting up the poll?  Or tearing it down? */
 
   pipecommon_semtake(&dev->d_bfsem);
-  for (i = 0; i < CONFIG_DEV_PIPE_NPOLLWAITERS; i++)
+  if (setup)
     {
-      /* Find the slot with the value equal to filep->f_priv.  If there
-       * is no previously installed poll structure, then f_priv will
-       * be NULL and we will find the first unused slot.  If f_priv is
-       * is non-NULL, then we will find the slot that was used for the
-       * previous setup.
+      /* This is a request to set up the poll.  Find an available
+       * slot for the poll structure reference
        */
 
-      if (dev->d_fds[i] == filep->f_priv)
+      for (i = 0; i < CONFIG_DEV_PIPE_NPOLLWAITERS; i++)
         {
-          dev->d_fds[i] = fds;
-          break;
-        }
-    }
+          /* Find an available slot */
 
-  if (i >= CONFIG_DEV_PIPE_NPOLLWAITERS)
-    {
-      DEBUGASSERT(fds != NULL);
-      return -EBUSY;
-    }
-
-  /* Set or clear the poll event structure reference in the 'struct file'
-   * private data.
-   */
+          if (!dev->d_fds[i])
+            {
+              /* Bind the poll structure and this slot */
 
-  filep->f_priv = fds;
+              dev->d_fds[i] = fds;
+              fds->private  = &dev->d_fds[i];
+              break;
+            }
+        }
 
-  /* Check if we should immediately notify on any of the requested events */
+      if (i >= CONFIG_DEV_PIPE_NPOLLWAITERS)
+        {
+          fds->private = NULL;
+          ret          = -EBUSY;
+          goto errout;
+        }
 
-  if (fds)
-    {
-      /* Determine how many bytes are in the buffer */
+      /* Should immediately notify on any of the requested events?
+       * First, determine how many bytes are in the buffer
+       */
 
       if (dev->d_wrndx >= dev->d_rdndx)
         {
@@ -599,9 +595,29 @@ int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds)
           pipecommon_pollnotify(dev, eventset);
         }
     }
+  else
+    {
+      /* This is a request to tear down the poll. */
+
+      struct pollfd **slot = (struct pollfd **)fds->private;
+
+#ifdef CONFIG_DEBUG
+      if (!slot)
+        {
+          ret              = -EIO;
+          goto errout;
+        }
+#endif
+
+      /* Remove all memory of the poll setup */
+
+      *slot                = NULL;
+      fds->private         = NULL;
+    }
 
+errout:
   sem_post(&dev->d_bfsem);
-  return OK;
+  return ret;
 }
 #endif
 
diff --git a/drivers/pipe_common.h b/drivers/pipe_common.h
index 05edd9ca2917381057a5f0becd006d643ac3ac6a..56fa4865b097ba506ce605c05744712624eacc93 100644
--- a/drivers/pipe_common.h
+++ b/drivers/pipe_common.h
@@ -123,7 +123,8 @@ EXTERN int     pipecommon_close(FAR struct file *filep);
 EXTERN ssize_t pipecommon_read(FAR struct file *, FAR char *, size_t);
 EXTERN ssize_t pipecommon_write(FAR struct file *, FAR const char *, size_t);
 #ifndef CONFIG_DISABLE_POLL
-EXTERN int     pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds);
+EXTERN int     pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds,
+                               boolean setup);
 #endif
 
 #undef EXTERN
diff --git a/drivers/serial.c b/drivers/serial.c
index 4e409fa06eb07b670f833f612a8555bc38fcb6b2..ddc7338bc155f409671dcbfd439b1063b144fe3e 100644
--- a/drivers/serial.c
+++ b/drivers/serial.c
@@ -79,7 +79,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
 static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
 static int     uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
 #ifndef CONFIG_DISABLE_POLL
-static int     uart_poll(FAR struct file *filep, FAR struct pollfd *fds);
+static int     uart_poll(FAR struct file *filep, FAR struct pollfd *fds, boolean setup);
 #endif
 
 /************************************************************************************
@@ -400,58 +400,57 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
  ****************************************************************************/
 
 #ifndef CONFIG_DISABLE_POLL
-int uart_poll(FAR struct file *filep, FAR struct pollfd *fds)
+int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, boolean setup)
 {
   FAR struct inode *inode = filep->f_inode;
   FAR uart_dev_t   *dev   = inode->i_private;
   pollevent_t       eventset;
   int               ndx;
+  int               ret   = OK;
   int               i;
 
   /* Some sanity checking */
+
 #if CONFIG_DEBUG
-  if (!dev)
+  if (!dev || !fds)
     {
       return -ENODEV;
     }
 #endif
 
-  /* Find an available slot for the poll structure reference */
+  /* Are we setting up the poll?  Or tearing it down? */
 
   uart_takesem(&dev->pollsem);
-  for (i = 0; i < CONFIG_DEV_CONSOLE_NPOLLWAITERS; i++)
+  if (setup)
     {
-      /* Find the slot with the value equal to filep->f_priv.  If there
-       * is no previously installed poll structure, then f_priv will
-       * be NULL and we will find the first unused slot.  If f_priv is
-       * is non-NULL, then we will find the slot that was used for the
-       * previous setup.
+      /* This is a request to set up the poll.  Find an available
+       * slot for the poll structure reference
        */
 
-      if (dev->fds[i] == filep->f_priv)
+      for (i = 0; i < CONFIG_DEV_CONSOLE_NPOLLWAITERS; i++)
         {
-          dev->fds[i] = fds;
-          break;
-        }
-    }
-
-  if (i >= CONFIG_DEV_CONSOLE_NPOLLWAITERS)
-    {
-      DEBUGASSERT(fds != NULL);
-      return -EBUSY;
-    }
+          /* Find an available slot */
 
-  /* Set or clear the poll event structure reference in the 'struct file'
-   * private data.
-   */
+          if (!dev->fds[i])
+            {
+              /* Bind the poll structure and this slot */
 
-  filep->f_priv = fds;
+              dev->fds[i]  = fds;
+              fds->private = &dev->fds[i];
+              break;
+            }
+        }
 
-  /* Check if we should immediately notify on any of the requested events */
+      if (i >= CONFIG_DEV_CONSOLE_NPOLLWAITERS)
+        {
+          fds->private = NULL;
+          ret          = -EBUSY;
+          goto errout;
+        }
 
-  if (fds)
-    {
-      /* Check if the xmit buffer is full. */
+      /* Should immediately notify on any of the requested events?
+       * First, check if the xmit buffer is full.
+       */
 
       eventset = 0;
 
@@ -480,10 +479,31 @@ int uart_poll(FAR struct file *filep, FAR struct pollfd *fds)
         {
           uart_pollnotify(dev, eventset);
         }
+
+    }
+  else if (fds->private)
+    {
+      /* This is a request to tear down the poll. */
+
+      struct pollfd **slot = (struct pollfd **)fds->private;
+
+#ifdef CONFIG_DEBUG
+      if (!slot)
+        {
+          ret              = -EIO;
+          goto errout;
+        }
+#endif
+
+      /* Remove all memory of the poll setup */
+
+      *slot                = NULL;
+      fds->private         = NULL;
     }
 
+errout:
   uart_givesem(&dev->pollsem);
-  return OK;
+  return ret;
 }
 #endif
 
diff --git a/examples/README.txt b/examples/README.txt
index 58de1ff8af791bf7416d33c4cb96125dfcb1fa4b..f6528e5f4b6b2854c71cd2ae269e4df6406d33b8 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -99,8 +99,7 @@ examples/poll
 ^^^^^^^^^^^^^
 
   A test of the poll() and select() APIs using FIFOs and, if available,
-  stdin, and a TCP/IP socket.  This example also includes a nice select
-  based TCP/IP server example.  In order to build this test, you must the
+  stdin, and a TCP/IP socket.  In order to build this test, you must the
   following selected in your NuttX configuration file:
 
   CONFIG_NFILE_DESCRIPTORS          - Defined to be greater than 0
@@ -114,6 +113,11 @@ examples/poll
   CONFIG_NSOCKET_DESCRIPTORS        - Defined to be greater than 0
   CONFIG_NET_NTCP_READAHEAD_BUFFERS - Defined to be greater than zero
 
+  CONFIG_EXAMPLE_POLL_NOMAC         - (May be defined to use software assigned MAC)
+  CONFIG_EXAMPLE_POLL_IPADDR        - Target IP address
+  CONFIG_EXAMPLE_POLL_DRIPADDR      - Default router IP addess
+  CONFIG_EXAMPLE_POLL_NETMASK       - Network mask
+
   In additional to the target device-side example, there is also
   a host-side application in this directory.  It can be compiled under
   Linux or Cygwin as follows:
diff --git a/examples/poll/Makefile b/examples/poll/Makefile
index 568d5f29af1f36d52a7a7a75cac7cf2bfeb396fc..b527199123f0f9102a425405b2266c3181deb796 100644
--- a/examples/poll/Makefile
+++ b/examples/poll/Makefile
@@ -38,7 +38,7 @@
 
 ASRCS	= 
 AOBJS	= $(ASRCS:.S=$(OBJEXT))
-CSRCS	= poll_main.c poll_listener.c select_listener.c net_listener.c
+CSRCS	= poll_main.c poll_listener.c select_listener.c net_listener.c net_reader.c
 COBJS	= $(CSRCS:.c=$(OBJEXT))
 
 SRCS	= $(ASRCS) $(CSRCS)
diff --git a/examples/poll/host.c b/examples/poll/host.c
index 722d351d8c6a2011e8cb54b723c9cda6fa90f079..a55c1843e2ace7862ab30164fa49d73c7607e27e 100644
--- a/examples/poll/host.c
+++ b/examples/poll/host.c
@@ -99,7 +99,7 @@ int main(int argc, char **argv, char **envp)
 
   myaddr.sin_family      = AF_INET;
   myaddr.sin_port        = htons(LISTENER_PORT);
-  myaddr.sin_addr.s_addr = htonl(inet_addr(TARGETIP));
+  myaddr.sin_addr.s_addr = inet_addr(TARGETIP);
 
   message("client: Connecting to %s...\n", TARGETIP);
   if (connect( sockfd, (struct sockaddr*)&myaddr, sizeof(struct sockaddr_in)) < 0)
@@ -111,7 +111,7 @@ int main(int argc, char **argv, char **envp)
 
   /* Then send and receive messages */
 
-  for (i = 0; ; i++);
+  for (i = 0; ; i++)
     {
       sprintf(outbuf, "Remote message %d", i);
       len = strlen(outbuf);
@@ -139,6 +139,8 @@ int main(int argc, char **argv, char **envp)
           message("client: recv failed: %d\n", errno);
           goto errout_with_socket;
         }
+
+      inbuf[nbytesrecvd] = '\0';
       message("client: Received '%s' (%d bytes)\n", inbuf, nbytesrecvd);
 
       if (nbytesrecvd != len)
diff --git a/examples/poll/net_listener.c b/examples/poll/net_listener.c
index d511bfd44e4a8a94d78d1221cd354005b845c0b5..bc9840cd80bc5950ed4b6cb16ab073f6cc7c9c14 100644
--- a/examples/poll/net_listener.c
+++ b/examples/poll/net_listener.c
@@ -52,6 +52,7 @@
 #include <errno.h>
 #include <debug.h>
 
+#include <net/uip/uip-lib.h>
 #include "poll_internal.h"
 
 /****************************************************************************
@@ -107,6 +108,7 @@ static boolean net_closeclient(struct net_listener_s *nls, int sd)
 
 static inline boolean net_incomingdata(struct net_listener_s *nls, int sd)
 {
+  char *ptr;
   int nbytes;
   int ret;
 
@@ -139,25 +141,26 @@ static inline boolean net_incomingdata(struct net_listener_s *nls, int sd)
       else
         {
           nls->buffer[ret]='\0';
-          message("poll_listener: Read '%s' (%d bytes)\n", sd, nls->buffer, ret);
+          message("poll_listener: Read '%s' (%d bytes)\n", nls->buffer, ret);
 
           /* Echo the data back to the client */
 
-          for (nbytes = ret; nbytes > 0; )
+          for (nbytes = ret, ptr = nls->buffer; nbytes > 0; )
             {
-              ret = send(sd, nls->buffer, nbytes, 0);
+              ret = send(sd, ptr, nbytes, 0);
               if (ret < 0)
                 {
                   if (errno != EINTR)
                     {
-                       message("net_listener: Send faile sd=%d: \n", sd, errno);
+                       message("net_listener: Send failed sd=%d: \n", sd, errno);
                        net_closeclient(nls, sd);
                        return FALSE;
                     }
                 }
               else
                 {
-                  nbytes += ret;
+                  nbytes -= ret;
+                  ptr    += ret;
                 }
             }
         }
@@ -271,6 +274,46 @@ static inline boolean net_mksocket(struct net_listener_s *nls)
   return TRUE;
 }
 
+/****************************************************************************
+ * Name: net_configure
+ ****************************************************************************/
+
+static void net_configure(void)
+{
+  struct in_addr addr;
+#if defined(CONFIG_EXAMPLE_POLL_NOMAC)
+  ubyte mac[IFHWADDRLEN];
+#endif
+
+  /* Configure uIP */
+  /* Many embedded network interfaces must have a software assigned MAC */
+
+#ifdef CONFIG_EXAMPLE_POLL_NOMAC
+  mac[0] = 0x00;
+  mac[1] = 0xe0;
+  mac[2] = 0xb0;
+  mac[3] = 0x0b;
+  mac[4] = 0xba;
+  mac[5] = 0xbe;
+  uip_setmacaddr("eth0", mac);
+#endif
+
+  /* Set up our host address */
+
+  addr.s_addr = HTONL(CONFIG_EXAMPLE_POLL_IPADDR);
+  uip_sethostaddr("eth0", &addr);
+
+  /* Set up the default router address */
+
+  addr.s_addr = HTONL(CONFIG_EXAMPLE_POLL_DRIPADDR);
+  uip_setdraddr("eth0", &addr);
+
+  /* Setup the subnet mask */
+
+  addr.s_addr = HTONL(CONFIG_EXAMPLE_POLL_NETMASK);
+  uip_setnetmask("eth0", &addr);
+}
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -287,6 +330,10 @@ void *net_listener(pthread_addr_t pvarg)
   int ret;
   int i;
 
+  /* Configure uIP */
+
+  net_configure();
+
   /* Set up a listening socket */
 
   memset(&nls, 0, sizeof(struct net_listener_s));
diff --git a/examples/poll/net_reader.c b/examples/poll/net_reader.c
new file mode 100644
index 0000000000000000000000000000000000000000..cdddca7901df04999ad54f3659d9032c96a1045d
--- /dev/null
+++ b/examples/poll/net_reader.c
@@ -0,0 +1,314 @@
+/****************************************************************************
+ * examples/poll/net_reader.c
+ *
+ *   Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <net/uip/uip-lib.h>
+#include "poll_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+#define IOBUFFER_SIZE 80
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: net_configure
+ ****************************************************************************/
+
+static void net_configure(void)
+{
+  struct in_addr addr;
+#if defined(CONFIG_EXAMPLE_POLL_NOMAC)
+  ubyte mac[IFHWADDRLEN];
+#endif
+
+  /* Configure uIP */
+  /* Many embedded network interfaces must have a software assigned MAC */
+
+#ifdef CONFIG_EXAMPLE_POLL_NOMAC
+  mac[0] = 0x00;
+  mac[1] = 0xe0;
+  mac[2] = 0xb0;
+  mac[3] = 0x0b;
+  mac[4] = 0xba;
+  mac[5] = 0xbe;
+  uip_setmacaddr("eth0", mac);
+#endif
+
+  /* Set up our host address */
+
+  addr.s_addr = HTONL(CONFIG_EXAMPLE_POLL_IPADDR);
+  uip_sethostaddr("eth0", &addr);
+
+  /* Set up the default router address */
+
+  addr.s_addr = HTONL(CONFIG_EXAMPLE_POLL_DRIPADDR);
+  uip_setdraddr("eth0", &addr);
+
+  /* Setup the subnet mask */
+
+  addr.s_addr = HTONL(CONFIG_EXAMPLE_POLL_NETMASK);
+  uip_setnetmask("eth0", &addr);
+}
+
+/****************************************************************************
+ * Name: net_receive
+ ****************************************************************************/
+
+static void net_receive(int sd)
+{
+  struct timeval timeout;
+  char buffer[IOBUFFER_SIZE];
+  char *ptr;
+  fd_set readset;
+  int nbytes;
+  int ret;
+
+  /* Set up the timeout */
+
+  timeout.tv_sec  = NET_LISTENER_DELAY;
+  timeout.tv_usec = 0;
+
+  /* Loop while we have the connection */
+
+  for (;;)
+    {
+      /* Wait for incoming message */
+
+      do
+        {
+          FD_ZERO(&readset);
+          FD_SET(sd, &readset);
+          ret = select(sd + 1, &readset, NULL, NULL, &timeout);
+        }
+      while (ret < 0 && errno == EINTR);
+
+      /* Something has happened */
+
+      if (ret < 0)
+        {
+          message("net_reader: select failed: %d\n", errno);
+          return;
+        }
+      else if (ret == 0)
+        {
+          message("net_reader: Timeout\n");
+        }
+      else
+        {
+          message("net_reader: Read data from sd=%d\n", sd);
+          memset(buffer, '?', IOBUFFER_SIZE); /* Just to make sure we really receive something */
+          ret = recv(sd, buffer, IOBUFFER_SIZE, 0);
+          if (ret < 0)
+            {
+              if (errno != EINTR)
+                {
+                  message("net_reader: recv failed sd=%d: %d\n", sd, errno);
+                  if (errno != EAGAIN)
+                    {
+                       return;
+                    }
+                }
+            }
+          else if (ret == 0)
+            {
+              message("net_reader: Client connection lost sd=%d\n", sd);
+              return;
+            }
+          else
+            {
+              buffer[ret]='\0';
+              message("net_reader: Read '%s' (%d bytes)\n", buffer, ret);
+
+              /* Echo the data back to the client */
+
+              for (nbytes = ret, ptr = buffer; nbytes > 0; )
+                {
+                  ret = send(sd, ptr, nbytes, 0);
+                  if (ret < 0)
+                    {
+                      if (errno != EINTR)
+                        {
+                           message("net_reader: Send failed sd=%d: %d\n", sd, errno);
+                           return;
+                        }
+                    }
+                  else
+                    {
+                      nbytes -= ret;
+                      ptr    += ret;
+                    }
+                }
+            }
+        }
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: net_reader
+ ****************************************************************************/
+
+void *net_reader(pthread_addr_t pvarg)
+{
+  struct sockaddr_in addr;
+#ifdef POLL_HAVE_SOLINGER
+  struct linger ling;
+#endif
+  int listensd;
+  int acceptsd;
+  socklen_t addrlen;
+  int optval;
+
+  /* Configure uIP */
+
+  net_configure();
+
+  /* Create a new TCP socket */
+
+  listensd = socket(PF_INET, SOCK_STREAM, 0);
+  if (listensd < 0)
+    {
+      message("net_reader: socket failure: %d\n", errno);
+      goto errout;
+    }
+
+  /* Set socket to reuse address */
+
+  optval = 1;
+  if (setsockopt(listensd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, sizeof(int)) < 0)
+    {
+      message("net_reader: setsockopt SO_REUSEADDR failure: %d\n", errno);
+      goto errout_with_listensd;
+    }
+
+  /* Bind the socket to a local address */
+
+  addr.sin_family      = AF_INET;
+  addr.sin_port        = HTONS(LISTENER_PORT);
+  addr.sin_addr.s_addr = INADDR_ANY;
+
+  if (bind(listensd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) < 0)
+    {
+      message("net_reader: bind failure: %d\n", errno);
+      goto errout_with_listensd;
+    }
+
+  /* Listen for connections on the bound TCP socket */
+
+  if (listen(listensd, 5) < 0)
+    {
+      message("net_reader: listen failure %d\n", errno);
+      goto errout_with_listensd;
+    }
+
+  /* Connection loop */
+
+  for (;;)
+    {
+      /* Accept only one connection */
+
+      message("net_reader: Accepting new connections on port %d\n", LISTENER_PORT);
+      addrlen = sizeof(struct sockaddr_in);
+      acceptsd = accept(listensd, (struct sockaddr*)&addr, &addrlen);
+      if (acceptsd < 0)
+        {
+          message("net_reader: accept failure: %d\n", errno);
+          continue;
+        }
+      message("net_reader: Connection accepted on sd=%d\n", acceptsd);
+
+      /* Configure to "linger" until all data is sent when the socket is closed */
+
+#ifdef POLL_HAVE_SOLINGER
+      ling.l_onoff  = 1;
+      ling.l_linger = 30;     /* timeout is seconds */
+      if (setsockopt(acceptsd, SOL_SOCKET, SO_LINGER, &ling, sizeof(struct linger)) < 0)
+        {
+        message("net_reader: setsockopt SO_LINGER failure: %d\n", errno);
+        goto errout_with_acceptsd;
+      }
+#endif
+
+      /* Handle incoming messsages on the connection. */
+
+      net_receive(acceptsd);
+
+      message("net_reader: Closing sd=%d\n", acceptsd);
+      close(acceptsd);
+    }
+
+#ifdef POLL_HAVE_SOLINGER
+errout_with_acceptsd:
+  close(acceptsd);
+#endif
+errout_with_listensd:
+  close(listensd);
+errout:
+  return NULL;
+}
diff --git a/examples/poll/poll_internal.h b/examples/poll/poll_internal.h
index 1644304ec2bf2b22e656d4426e9e736e46744d56..38a5e0f7e52d6e4ceb427a4e455ddf94d040e86f 100644
--- a/examples/poll/poll_internal.h
+++ b/examples/poll/poll_internal.h
@@ -110,5 +110,6 @@ extern void *select_listener(pthread_addr_t pvarg);
 
 #ifdef HAVE_NETPOLL
 extern void *net_listener(pthread_addr_t pvarg);
+extern void *net_reader(pthread_addr_t pvarg);
 #endif
 #endif /* __EXAMPLES_PIPE_PIPE_H */
diff --git a/examples/poll/poll_main.c b/examples/poll/poll_main.c
index 2f84ed2003239949d99982435e7ecc6ad9795fb3..713c77e3a3184a4bccde69b0b31be8098d3e56a6 100644
--- a/examples/poll/poll_main.c
+++ b/examples/poll/poll_main.c
@@ -156,9 +156,15 @@ int user_start(int argc, char *argv[])
     }
 
 #ifdef HAVE_NETPOLL
+#if 0 /* select doesn't work for connections yet */
   message("user_start: Starting net_listener thread\n");
 
   ret = pthread_create(&tid3, NULL, net_listener, NULL);
+#else
+  message("user_start: Starting net_reader thread\n");
+
+  ret = pthread_create(&tid3, NULL, net_reader, NULL);
+#endif
   if (ret != 0)
     {
       message("user_start: Failed to create net_listener thread: %d\n", ret);
diff --git a/fs/fs_poll.c b/fs/fs_poll.c
index 133f16f4974caa2466b7ce7fd685e1c02fc5bc3c..fb0600f9d34d7033d3ceabead046b3c3cf007264 100644
--- a/fs/fs_poll.c
+++ b/fs/fs_poll.c
@@ -93,7 +93,7 @@ static void poll_semtake(FAR sem_t *sem)
  ****************************************************************************/
 
 #if CONFIG_NFILE_DESCRIPTORS > 0
-static int poll_fdsetup(int fd, FAR struct pollfd *fds)
+static int poll_fdsetup(int fd, FAR struct pollfd *fds, boolean setup)
 {
   FAR struct filelist *list;
   FAR struct file     *this_file;
@@ -109,7 +109,7 @@ static int poll_fdsetup(int fd, FAR struct pollfd *fds)
 #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
       if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS))
         {
-          return net_poll(fd, fds);
+          return net_poll(fd, fds, setup);
         }
       else
 #endif
@@ -137,7 +137,7 @@ static int poll_fdsetup(int fd, FAR struct pollfd *fds)
     {
       /* Yes, then setup the poll */
 
-      ret = (int)inode->u.i_ops->poll(this_file, fds);
+      ret = (int)inode->u.i_ops->poll(this_file, fds, setup);
     }
   return ret;
 }
@@ -168,7 +168,7 @@ static inline int poll_setup(FAR struct pollfd *fds, nfds_t nfds, sem_t *sem)
 
       /* Set up the poll */
 
-      ret = poll_fdsetup(fds[i].fd, &fds[i]);
+      ret = poll_fdsetup(fds[i].fd, &fds[i], TRUE);
       if (ret < 0)
         {
           return ret;
@@ -201,7 +201,7 @@ static inline int poll_teardown(FAR struct pollfd *fds, nfds_t nfds, int *count)
     {
       /* Teardown the poll */
 
-      status = poll_fdsetup(fds[i].fd, NULL);
+      status = poll_fdsetup(fds[i].fd, &fds[i], FALSE);
       if (status < 0)
         {
           ret = status;
diff --git a/include/nuttx/fs.h b/include/nuttx/fs.h
index ced7beed1c95c45bb3402b2c6075be4cdb182986..3d23706880199f4f6ac71738cbaeb92fb174ff7f 100644
--- a/include/nuttx/fs.h
+++ b/include/nuttx/fs.h
@@ -76,7 +76,7 @@ struct file_operations
   off_t   (*seek)(FAR struct file *filp, off_t offset, int whence);
   int     (*ioctl)(FAR struct file *filp, int cmd, unsigned long arg);
 #ifndef CONFIG_DISABLE_POLL
-  int     (*poll)(FAR struct file *filp, struct pollfd *fds);
+  int     (*poll)(FAR struct file *filp, struct pollfd *fds, boolean setup);
 #endif
 
   /* The two structures need not be common after this point */
diff --git a/include/nuttx/net.h b/include/nuttx/net.h
index e28f28b5cf1ffafc8af07197b147f3697dd37b99..b6bdfbe74fde721a3f8d8425011266f5576c3001 100644
--- a/include/nuttx/net.h
+++ b/include/nuttx/net.h
@@ -95,12 +95,6 @@ struct socket
 #endif
 #endif
   void         *s_conn;      /* Connection: struct uip_conn or uip_udp_conn */
-
-  /* The socket poll logic needs a place to retain state info */
-
-#if !defined(CONFIG_DISABLE_POLL) && defined(CONFIG_NET_TCP) && CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
-  FAR void   *private;
-#endif
 };
 
 /* This defines a list of sockets indexed by the socket descriptor */
@@ -166,7 +160,7 @@ EXTERN int netdev_ioctl(int sockfd, int cmd, struct ifreq *req);
 
 #ifndef CONFIG_DISABLE_POLL
 struct pollfd; /* Forward reference -- see poll.h */
-EXTERN int net_poll(int sockfd, struct pollfd *fds);
+EXTERN int net_poll(int sockfd, struct pollfd *fds, boolean setup);
 #endif
 
 /* netdev-register.c *********************************************************/
diff --git a/include/poll.h b/include/poll.h
index e82d48f57ce6461479c2aae7ff07eefced216a3c..3b41ec99adb9477bbf9eba93b41978f45335320e 100644
--- a/include/poll.h
+++ b/include/poll.h
@@ -108,6 +108,7 @@ struct pollfd
   sem_t      *sem;      /* Pointer to semaphore used to post output event */
   pollevent_t events;   /* The input event flags */
   pollevent_t revents;  /* The output event flags */
+  FAR void   *private;  /* For use by drivers */
 };
 
 /****************************************************************************
diff --git a/net/net-poll.c b/net/net-poll.c
index a0197e26d25ca14806cdd7a506e631c7315161c3..22bd03ce9c25f8de9a8ff3280ba9190edf4d46b6 100644
--- a/net/net-poll.c
+++ b/net/net-poll.c
@@ -172,7 +172,7 @@ static inline int net_pollsetup(FAR struct socket *psock, struct pollfd *fds)
   /* Sanity check */
 
 #ifdef CONFIG_DEBUG
-  if (!conn || !fds || psock->private)
+  if (!conn || !fds)
     {
       ret = -EINVAL;
       goto errout;
@@ -200,7 +200,7 @@ static inline int net_pollsetup(FAR struct socket *psock, struct pollfd *fds)
 
   /* Save the nps reference in the poll structure for use at teardown as well */
 
-  psock->private = (FAR void *)cb;
+  fds->private = (FAR void *)cb;
 
   /* Check for read data availability now */
 
@@ -239,7 +239,7 @@ errout:
  ****************************************************************************/
 
 #ifdef HAVE_NETPOLL
-static inline int net_pollteardown(FAR struct socket *psock)
+static inline int net_pollteardown(FAR struct socket *psock, struct pollfd *fds)
 {
   FAR struct uip_conn *conn = psock->s_conn;
   FAR struct uip_callback_s *cb;
@@ -248,7 +248,7 @@ static inline int net_pollteardown(FAR struct socket *psock)
   /* Sanity check */
 
 #ifdef CONFIG_DEBUG
-  if (!conn || !psock->private)
+  if (!conn || !fds->private)
     {
       return -EINVAL;
     }
@@ -256,7 +256,7 @@ static inline int net_pollteardown(FAR struct socket *psock)
 
   /* Recover the socket descriptor poll state info from the poll structure */
 
-  cb = (FAR struct uip_callback_s *)psock->private;
+  cb = (FAR struct uip_callback_s *)fds->private;
   if (cb)
     {
       /* Release the callback */
@@ -267,7 +267,7 @@ static inline int net_pollteardown(FAR struct socket *psock)
 
       /* Release the poll/select data slot */
 
-      psock->private = NULL;
+      fds->private = NULL;
     }
 
   return OK;
@@ -286,9 +286,10 @@ static inline int net_pollteardown(FAR struct socket *psock)
  *   to this function.
  *
  * Input Parameters:
- *   fd   - The socket descriptor of interest
- *   fds  - The structure describing the events to be monitored, OR NULL if
- *          this is a request to stop monitoring events.
+ *   fd    - The socket descriptor of interest
+ *   fds   - The structure describing the events to be monitored, OR NULL if
+ *           this is a request to stop monitoring events.
+ *   setup - TRUE: Setup up the poll; FALSE: Teardown the poll
  *
  * Returned Value:
  *  0: Success; Negated errno on failure
@@ -296,7 +297,7 @@ static inline int net_pollteardown(FAR struct socket *psock)
  ****************************************************************************/
 
 #ifndef CONFIG_DISABLE_POLL
-int net_poll(int sockfd, struct pollfd *fds)
+int net_poll(int sockfd, struct pollfd *fds, boolean setup)
 {
 #ifndef HAVE_NETPOLL
   return -ENOSYS;
@@ -326,7 +327,7 @@ int net_poll(int sockfd, struct pollfd *fds)
 #endif
 
   /* Check if we are setting up or tearing down the poll */
-  if (fds)
+  if (setup)
     {
       /* Perform the TCP/IP poll() setup */
 
@@ -336,7 +337,7 @@ int net_poll(int sockfd, struct pollfd *fds)
     {
       /* Perform the TCP/IP poll() teardown */
 
-      ret = net_pollteardown(psock);
+      ret = net_pollteardown(psock, fds);
     }
 
 errout: