[rtems commit] PR2158: Add support for dup2.

Chris Johns chrisj at rtems.org
Tue Dec 10 01:30:55 UTC 2013


Module:    rtems
Branch:    master
Commit:    6122cb6af67c88550fecaa786c1dfd3bc1ceb1d1
Changeset: http://git.rtems.org/rtems/commit/?id=6122cb6af67c88550fecaa786c1dfd3bc1ceb1d1

Author:    Chris Johns <chrisj at rtems.org>
Date:      Tue Dec 10 12:35:29 2013 +1100

PR2158: Add support for dup2.

Split the dub call into dup and dup2 in fcntl.c. This requires
a private command which is placed in the internal libio header.

---

 cpukit/libcsupport/include/rtems/libio_.h |    7 ++++
 cpukit/libcsupport/src/dup2.c             |    2 +-
 cpukit/libcsupport/src/fcntl.c            |   53 +++++++++++++++++++++++++---
 3 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/cpukit/libcsupport/include/rtems/libio_.h b/cpukit/libcsupport/include/rtems/libio_.h
index 8856566..bf01cd5 100644
--- a/cpukit/libcsupport/include/rtems/libio_.h
+++ b/cpukit/libcsupport/include/rtems/libio_.h
@@ -42,6 +42,13 @@ extern "C" {
 #define RTEMS_FILESYSTEM_SYMLOOP_MAX 32
 
 /*
+ * Not defined in newlib so provide here. Users should use dup2 and
+ * not this non-portable fcntl command. Provided here to allow the
+ * RTEMS implementation to work.
+ */
+#define F_DUP2FD 20
+
+/*
  *  Semaphore to protect the io table
  */
 
diff --git a/cpukit/libcsupport/src/dup2.c b/cpukit/libcsupport/src/dup2.c
index 37c93a7..ac6f0a1 100644
--- a/cpukit/libcsupport/src/dup2.c
+++ b/cpukit/libcsupport/src/dup2.c
@@ -54,5 +54,5 @@ int dup2(
    *  This fcntl handles everything else.
    */
 
-  return fcntl( fildes, F_DUPFD, fildes2 );
+  return fcntl( fildes, F_DUP2FD, fildes2 );
 }
diff --git a/cpukit/libcsupport/src/fcntl.c b/cpukit/libcsupport/src/fcntl.c
index 53feb66..d422a48 100644
--- a/cpukit/libcsupport/src/fcntl.c
+++ b/cpukit/libcsupport/src/fcntl.c
@@ -24,14 +24,10 @@
 
 #include <rtems/libio_.h>
 
-static int duplicate_iop( rtems_libio_t *iop, int fd2 )
+static int duplicate_iop( rtems_libio_t *iop )
 {
   int rv = 0;
 
-  /*
-   * FIXME: We ignore the start value fd2 for the file descriptor search.  This
-   * is not POSIX conform.
-   */
   rtems_libio_t *diop = rtems_libio_allocate();
 
   if (diop != NULL) {
@@ -62,6 +58,47 @@ static int duplicate_iop( rtems_libio_t *iop, int fd2 )
   return rv;
 }
 
+static int duplicate2_iop( rtems_libio_t *iop, int fd2 )
+{
+  rtems_libio_t *iop2;
+  int            rv = 0;
+
+  rtems_libio_check_fd( fd2 );
+  iop2 = rtems_libio_iop( fd2 );
+
+  if (iop != iop2)
+  {
+    int oflag;
+
+    if ((iop2->flags & LIBIO_FLAGS_OPEN) != 0) {
+      rv = (*iop2->pathinfo.handlers->close_h)( iop2 );
+    }
+
+    if (rv == 0) {
+      oflag = rtems_libio_to_fcntl_flags( iop->flags );
+      oflag &= ~O_CREAT;
+      iop2->flags |= rtems_libio_fcntl_flags( oflag );
+
+      rtems_filesystem_instance_lock( &iop->pathinfo );
+      rtems_filesystem_location_clone( &iop2->pathinfo, &iop->pathinfo );
+      rtems_filesystem_instance_unlock( &iop->pathinfo );
+
+      /*
+       * XXX: We call the open handler here to have a proper open and close
+       *      pair.
+       *
+       * FIXME: What to do with the path?
+       */
+      rv = (*iop2->pathinfo.handlers->open_h)( iop2, NULL, oflag, 0 );
+      if ( rv == 0 ) {
+        rv = fd2;
+      }
+    }
+  }
+
+  return rv;
+}
+
 static int vfcntl(
   int fd,
   int cmd,
@@ -88,8 +125,12 @@ static int vfcntl(
 
   switch ( cmd ) {
     case F_DUPFD:        /* dup */
+      ret = duplicate_iop( iop );
+      break;
+
+    case F_DUP2FD:       /* dup2 */
       fd2 = va_arg( ap, int );
-      ret = duplicate_iop( iop, fd2 );
+      ret = duplicate2_iop( iop, fd2 );
       break;
 
     case F_GETFD:        /* get f_flags */




More information about the vc mailing list