diff --git a/fs/fs_dup.c b/fs/fs_dup.c
index 20b7fbf279c9c1da71fc79a419733ae3bbc998c0..c041aa4ca1ab27d0dd410dd71cee7cec14c78ea2 100644
--- a/fs/fs_dup.c
+++ b/fs/fs_dup.c
@@ -47,15 +47,8 @@
 #include <nuttx/fs.h>
 #include "fs_internal.h"
 
-/* This logic in this applies only when both socket and file descriptors are
- * in that case, this function descriminates which type of dup is being
- * performed.
- */
-
-#if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
-
 /****************************************************************************
- * Definitions
+ * Pre-processor Definitions
  ****************************************************************************/
 
 /****************************************************************************
@@ -76,34 +69,40 @@
 
 int dup(int fildes)
 {
+ int ret = OK;
+
   /* Check the range of the descriptor to see if we got a file or a socket
    * descriptor. */
 
-  if ((unsigned int)fildes >= CONFIG_NFILE_DESCRIPTORS)
+#if CONFIG_NFILE_DESCRIPTORS > 0
+  if ((unsigned int)fildes < CONFIG_NFILE_DESCRIPTORS)
+    {
+      /* Its a valid file descriptor.. dup the file descriptor using any
+       * other file descriptor*/
+
+      ret = file_dup(fildes, 0);
+    }
+  else
+#endif
     {
       /* Not a vailid file descriptor.  Did we get a valid socket descriptor? */
 
+#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
       if ((unsigned int)fildes < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS))
         {
           /* Yes.. dup the socket descriptor */
 
-          return net_dup(fildes);
+          ret = net_dup(fildes, CONFIG_NFILE_DESCRIPTORS);
         }
       else
+#endif
         {
           /* No.. then it is a bad descriptor number */
 
           errno = EBADF;
-          return ERROR;
+          ret = ERROR;
         }
     }
-  else
-    {
-      /* Its a valid file descriptor.. dup the file descriptor */
-
-      return file_dup(fildes);
-    }
+  return ret;
 }
 
-#endif /* CONFIG_NFILE_DESCRIPTORS > 0 ... */
-
diff --git a/fs/fs_fcntl.c b/fs/fs_fcntl.c
index 524bd22b0ccfa1441c0a9c4d42e274940f345afd..d8afd51a205268273b57b4340c7e1f1fc7fc2859 100644
--- a/fs/fs_fcntl.c
+++ b/fs/fs_fcntl.c
@@ -94,6 +94,11 @@ static inline int file_vfcntl(int fildes, int cmd, va_list ap)
          * exec functions.
          */
 
+        {
+          ret = file_dup(fildes, va_arg(ap, int));
+        }
+        break;
+
       case F_GETFD:
         /* Get the file descriptor flags defined in <fcntl.h> that are associated
          * with the file descriptor fildes.  File descriptor flags are associated
diff --git a/fs/fs_filedup.c b/fs/fs_filedup.c
index 71f625877d4310e26dcbd5b544c534d987611653..10c2eba04b4c7e0c8c7eb9e5c35890f448ef6d7c 100644
--- a/fs/fs_filedup.c
+++ b/fs/fs_filedup.c
@@ -40,7 +40,6 @@
 #include <nuttx/config.h>
 
 #include <sys/types.h>
-#include <unistd.h>
 #include <sched.h>
 #include <errno.h>
 
@@ -76,11 +75,7 @@
  *
  ****************************************************************************/
 
-#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
-int file_dup(int fildes)
-#else
-int dup(int fildes)
-#endif
+int file_dup(int fildes, int minfd)
 {
   FAR struct filelist *list;
   int fildes2;
@@ -110,7 +105,8 @@ int dup(int fildes)
 
   fildes2 = files_allocate(list->fl_files[fildes].f_inode,
                            list->fl_files[fildes].f_oflags,
-                           list->fl_files[fildes].f_pos);
+                           list->fl_files[fildes].f_pos,
+                           minfd);
   if (fildes2 < 0)
     {
       errno = EMFILE;
diff --git a/fs/fs_files.c b/fs/fs_files.c
index d0c3fff529d07e68a5c4807188c28f0b90b4ae53..e872d155842e6498b5c3a9d1194dd56e6e48ad17 100644
--- a/fs/fs_files.c
+++ b/fs/fs_files.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  * fs/fs_files.c
  *
- *   Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -361,7 +361,8 @@ errout:
  *   Returns the file descriptor == index into the files array.
  *
  ****************************************************************************/
-int files_allocate(FAR struct inode *inode, int oflags, off_t pos)
+
+int files_allocate(FAR struct inode *inode, int oflags, off_t pos, int minfd)
 {
   FAR struct filelist *list;
   int i;
@@ -370,7 +371,7 @@ int files_allocate(FAR struct inode *inode, int oflags, off_t pos)
   if (list)
     {
       _files_semtake(list);
-      for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
+      for (i = minfd; i < CONFIG_NFILE_DESCRIPTORS; i++)
         {
           if (!list->fl_files[i].f_inode)
             {
diff --git a/fs/fs_internal.h b/fs/fs_internal.h
index e34c451342f5464a4d5f3d66322455623f47d029..34b722e982194ca3701301de88d4135ea3d46077 100644
--- a/fs/fs_internal.h
+++ b/fs/fs_internal.h
@@ -225,7 +225,7 @@ EXTERN void inode_release(FAR struct inode *inode);
 /* fs_files.c ****************************************************************/
 
 EXTERN void weak_function files_initialize(void);
-EXTERN int  files_allocate(FAR struct inode *inode, int oflags, off_t pos);
+EXTERN int  files_allocate(FAR struct inode *inode, int oflags, off_t pos, int minfd);
 EXTERN int  files_close(int filedes);
 EXTERN void files_release(int filedes);
 
diff --git a/fs/fs_open.c b/fs/fs_open.c
index 8ab6503769d23e66042b7d1434d3e5ad3e69b830..76b941f95992273672c6dda3ee640035368d5452 100644
--- a/fs/fs_open.c
+++ b/fs/fs_open.c
@@ -140,7 +140,7 @@ int open(const char *path, int oflags, ...)
 
   /* Associate the inode with a file structure */
 
-  fd = files_allocate(inode, oflags, 0);
+  fd = files_allocate(inode, oflags, 0, 0);
   if (fd < 0)
     {
       ret = EMFILE;
diff --git a/include/nuttx/fs.h b/include/nuttx/fs.h
index b33bfa234cf4f4ef2c5df440be34b611c137ecbe..a0c70390ddfa529b678ff9d9a3d9ec790a93881e 100644
--- a/include/nuttx/fs.h
+++ b/include/nuttx/fs.h
@@ -344,15 +344,9 @@ EXTERN int files_dup(FAR struct file *filep1, FAR struct file *filep2);
 
 /* fs_filedup.c **************************************************************/
 
-/* This alternative naming is used when dup could operate on both file and
- * socket descritors to avoid drawing unused socket support into the link.
- */
+/* Dupicate a file descriptor using any value greater than or equal to minfd */
 
-#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
-EXTERN int file_dup(int fd);
-#else
-#  define file_dup(fd)        dup(fd)
-#endif
+EXTERN int file_dup(int fd, int minfd);
 
 /* fs_filedup2.c *************************************************************/
 
diff --git a/include/nuttx/net.h b/include/nuttx/net.h
index efe897073f4a3b2c09f5c36456d2425f6c5ce769..db29524b66c181eeb3b9823f15cce3ba22be34f5 100644
--- a/include/nuttx/net.h
+++ b/include/nuttx/net.h
@@ -166,14 +166,10 @@ EXTERN int net_poll(int sockfd, struct pollfd *fds, boolean setup);
 
 /* net_dup.c *****************************************************************/
 /* The standard dup() operation redirects operations on socket descriptors to
- * this function (when both file and socket descriptors are supported)
+ * this function
  */
 
-#if CONFIG_NFILE_DESCRIPTOR > 0
-EXTERN int net_dup(int sockfd);
-#else
-#  define net_dup(sockfd) dup(sockfd)
-#endif
+EXTERN int net_dup(int sockfd, int minsd);
 
 /* net_dup2.c ****************************************************************/
 /* The standard dup2() operation redirects operations on socket descriptors to
diff --git a/net/accept.c b/net/accept.c
index a9701b2d5464af14b7ad25b826a4fdf623387e18..c2e64153c6420fb017dc0f3ec7a083939a1ce73b 100644
--- a/net/accept.c
+++ b/net/accept.c
@@ -318,7 +318,7 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
    * (so that it cannot fail later)
    */
 
-  newfd = sockfd_allocate();
+  newfd = sockfd_allocate(0);
   if (newfd < 0)
     {
       err = ENFILE;
diff --git a/net/net_dup.c b/net/net_dup.c
index f4ee15abed3e4fc88d5413fc8f36d1298ba911d6..e935e4749744ad37550de956981443a9524621e7 100644
--- a/net/net_dup.c
+++ b/net/net_dup.c
@@ -49,12 +49,16 @@
 
 #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
 
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
 /****************************************************************************
  * Global Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Function: net_dup OR dup
+ * Function: net_dup
  *
  * Description:
  *   Clone a socket descriptor to an arbitray descriptor number.  If file
@@ -64,11 +68,7 @@
  *
  ****************************************************************************/
 
-#if CONFIG_NFILE_DESCRIPTOR > 0
-int net_dup(int sockfd)
-#else
-int dup(int sockfd)
-#endif
+int net_dup(int sockfd, int minsd)
 {
   FAR struct socket *psock1 = sockfd_socket(sockfd);
   FAR struct socket *psock2;
@@ -76,6 +76,22 @@ int dup(int sockfd)
   int err;
   int ret;
 
+  /* Make sure that the minimum socket descriptor is within the legal range.
+   * the minimum value we receive is relative to file descriptor 0;  we need
+   * map it relative of the first socket descriptor.
+   */
+
+#if CONFIG_NFILE_DESCRIPTORS > 0
+  if (minsd >= CONFIG_NFILE_DESCRIPTORS)
+    {
+      minsd -= CONFIG_NFILE_DESCRIPTORS;
+    }
+  else
+    {
+      minsd = 0;
+    }
+#endif
+
   /* Lock the scheduler throughout the following */
 
   sched_lock();
@@ -94,7 +110,7 @@ int dup(int sockfd)
 
   /* Allocate a new socket descriptor */
 
-  sockfd2 = sockfd_allocate();
+  sockfd2 = sockfd_allocate(minsd);
   if (sockfd2 < 0)
     {
       err = ENFILE;
diff --git a/net/net_internal.h b/net/net_internal.h
index 9afa408beef7ce0de907651aaeb8a962c397e07f..a403a269faf4910ab8ea31c75eac97bfe07ab378 100644
--- a/net/net_internal.h
+++ b/net/net_internal.h
@@ -144,7 +144,7 @@ extern "C" {
 
 /* net_sockets.c *************************************************************/
 
-EXTERN int  sockfd_allocate(void);
+EXTERN int  sockfd_allocate(int minsd);
 EXTERN void sockfd_release(int sockfd);
 EXTERN FAR struct socket *sockfd_socket(int sockfd);
 
diff --git a/net/net_sockets.c b/net/net_sockets.c
index cda0c105e9322b0905dac90d72f130ff3b77dab2..3db69519d8a74a16e20754fbdfc84b3ef4fc47b9 100644
--- a/net/net_sockets.c
+++ b/net/net_sockets.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  * net_sockets.c
  *
- *   Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2007- 2009 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -192,7 +192,7 @@ int net_releaselist(FAR struct socketlist *list)
   return OK;
 }
 
-int sockfd_allocate(void)
+int sockfd_allocate(int minsd)
 {
   FAR struct socketlist *list;
   int i;
@@ -205,14 +205,16 @@ int sockfd_allocate(void)
       /* Search for a socket structure with no references */
 
       _net_semtake(list);
-      for (i = 0; i < CONFIG_NSOCKET_DESCRIPTORS; i++)
+      for (i = minsd; i < CONFIG_NSOCKET_DESCRIPTORS; i++)
         {
           /* Are there references on this socket? */
+
           if (!list->sl_sockets[i].s_crefs)
             {
               /* No take the reference and return the index + an offset
                * as the socket descriptor.
                */
+
                memset(&list->sl_sockets[i], 0, sizeof(struct socket));
                list->sl_sockets[i].s_crefs = 1;
                _net_semgive(list);
diff --git a/net/net_vfcntl.c b/net/net_vfcntl.c
index bf3e37d814e9579c4f9e93e84edf1c22440bdaf6..537a9031d5d7d335ad61a8306d6bc854706947e7 100644
--- a/net/net_vfcntl.c
+++ b/net/net_vfcntl.c
@@ -49,6 +49,10 @@
 
 #if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
 
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
 /****************************************************************************
  * Global Functions
  ****************************************************************************/
@@ -67,7 +71,7 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
       goto errout;
     }
 
-#warning "fcntl() commands not yet implemented"
+#warning "Most fcntl() commands not yet implemented"
   switch (cmd)
     {
       case F_DUPFD:
@@ -81,6 +85,11 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
          * exec functions.
          */
 
+        {
+          ret = net_dup(sockfd, va_arg(ap, int));
+        }
+        break;
+
       case F_GETFD:
         /* Get the file descriptor flags defined in <fcntl.h> that are associated
          * with the file descriptor fildes.  File descriptor flags are associated
diff --git a/net/socket.c b/net/socket.c
index fddff2ccc7e6da1e46cd9699f6851174816a112c..f8de67f9e2951e815a371501812e443f25cdf199 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -126,7 +126,7 @@ int socket(int domain, int type, int protocol)
 
   /* Everything looks good.  Allocate a socket descriptor */
 
-  sockfd = sockfd_allocate();
+  sockfd = sockfd_allocate(0);
   if (sockfd < 0)
     {
       err = ENFILE;