summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2013-12-10 12:35:29 +1100
committerChris Johns <chrisj@rtems.org>2013-12-10 12:35:29 +1100
commit6122cb6af67c88550fecaa786c1dfd3bc1ceb1d1 (patch)
treed35fe1e1d22d2f2844db1058bd60a6f38d8170f8
parentPR2159: Have the FIFO driver read follow POSIX standard. (diff)
downloadrtems-6122cb6af67c88550fecaa786c1dfd3bc1ceb1d1.tar.bz2
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.
-rw-r--r--cpukit/libcsupport/include/rtems/libio_.h7
-rw-r--r--cpukit/libcsupport/src/dup2.c2
-rw-r--r--cpukit/libcsupport/src/fcntl.c53
3 files changed, 55 insertions, 7 deletions
diff --git a/cpukit/libcsupport/include/rtems/libio_.h b/cpukit/libcsupport/include/rtems/libio_.h
index 885656616f..bf01cd5659 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 37c93a7398..ac6f0a1b62 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 53feb669b1..d422a48936 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 */