summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport/src/fcntl.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libcsupport/src/fcntl.c')
-rw-r--r--cpukit/libcsupport/src/fcntl.c60
1 files changed, 41 insertions, 19 deletions
diff --git a/cpukit/libcsupport/src/fcntl.c b/cpukit/libcsupport/src/fcntl.c
index 988a9414ee..10f783b910 100644
--- a/cpukit/libcsupport/src/fcntl.c
+++ b/cpukit/libcsupport/src/fcntl.c
@@ -12,17 +12,53 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
-#include <errno.h>
-#include <rtems.h>
#include <rtems/libio_.h>
+static int duplicate_iop( rtems_libio_t *iop, int fd2 )
+{
+ 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) {
+ int oflag = rtems_libio_to_fcntl_flags( iop->flags );
+
+ oflag &= ~O_CREAT;
+ diop->flags |= rtems_libio_fcntl_flags( oflag );
+
+ rtems_filesystem_instance_lock( &iop->pathinfo );
+ rtems_filesystem_location_clone( &diop->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 = (*diop->pathinfo.handlers->open_h)( diop, NULL, oflag, 0 );
+ if ( rv == 0 ) {
+ rv = diop - rtems_libio_iops;
+ } else {
+ rtems_libio_free( diop );
+ }
+ } else {
+ rv = -1;
+ }
+
+ return rv;
+}
+
static int vfcntl(
int fd,
int cmd,
@@ -30,7 +66,6 @@ static int vfcntl(
)
{
rtems_libio_t *iop;
- rtems_libio_t *diop;
int fd2;
int flags;
int mask;
@@ -51,20 +86,7 @@ static int vfcntl(
switch ( cmd ) {
case F_DUPFD: /* dup */
fd2 = va_arg( ap, int );
- if ( fd2 )
- diop = rtems_libio_iop( fd2 );
- else {
- /* allocate a file control block */
- diop = rtems_libio_allocate();
- if ( diop == 0 ) {
- ret = -1;
- break;
- }
- }
-
- diop->flags = iop->flags;
- diop->pathinfo = iop->pathinfo;
- ret = (int) (diop - rtems_libio_iops);
+ ret = duplicate_iop( iop, fd2 );
break;
case F_GETFD: /* get f_flags */
@@ -138,7 +160,7 @@ static int vfcntl(
*/
if (ret >= 0) {
- int err = (*iop->pathinfo.handlers->fcntl_h)( cmd, iop );
+ int err = (*iop->pathinfo.handlers->fcntl_h)( iop, cmd );
if (err) {
errno = err;
ret = -1;