summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1999-03-19 21:51:58 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1999-03-19 21:51:58 +0000
commitaf0200363e8d0a69648bd78fd5ee2d0ee5f40624 (patch)
tree5134c59a5e4afdf27dec4559ad764a099a66c5e1 /c
parentPatch from Ralf Corsepius <corsepiu@faw.uni-ulm.de>: (diff)
downloadrtems-af0200363e8d0a69648bd78fd5ee2d0ee5f40624.tar.bz2
Patch from Eric Norum <eric@skatter.usask.ca> that adds external
fcntl support and an external fcntl handler for sockets.
Diffstat (limited to 'c')
-rw-r--r--c/src/exec/libcsupport/include/rtems/libio.h6
-rw-r--r--c/src/exec/libcsupport/src/fcntl.c60
-rw-r--r--c/src/exec/libnetworking/rtems/rtems_syscall.c34
-rw-r--r--c/src/lib/include/rtems/libio.h6
-rw-r--r--c/src/lib/libc/fcntl.c60
-rw-r--r--c/src/lib/libc/libio.h6
-rw-r--r--c/src/lib/libnetworking/rtems/rtems_syscall.c34
-rw-r--r--c/src/libnetworking/rtems/rtems_syscall.c34
8 files changed, 180 insertions, 60 deletions
diff --git a/c/src/exec/libcsupport/include/rtems/libio.h b/c/src/exec/libcsupport/include/rtems/libio.h
index 1cbfef383b..6ded1e361d 100644
--- a/c/src/exec/libcsupport/include/rtems/libio.h
+++ b/c/src/exec/libcsupport/include/rtems/libio.h
@@ -115,6 +115,11 @@ typedef int (*rtems_filesystem_fdatasync_t)(
rtems_libio_t *iop
);
+typedef int (*rtems_filesystem_fcntl_t)(
+ int cmd,
+ rtems_libio_t *iop
+);
+
typedef struct {
rtems_filesystem_open_t open;
rtems_filesystem_close_t close;
@@ -128,6 +133,7 @@ typedef struct {
rtems_filesystem_fpathconf_t fpathconf;
rtems_filesystem_fsync_t fsync;
rtems_filesystem_fdatasync_t fdatasync;
+ rtems_filesystem_fcntl_t fcntl;
} rtems_filesystem_file_handlers_r;
/*
diff --git a/c/src/exec/libcsupport/src/fcntl.c b/c/src/exec/libcsupport/src/fcntl.c
index 381df45f26..3a65a74574 100644
--- a/c/src/exec/libcsupport/src/fcntl.c
+++ b/c/src/exec/libcsupport/src/fcntl.c
@@ -30,6 +30,7 @@ int fcntl(
rtems_libio_t *diop;
int fd2;
int flags;
+ int ret = 0;
va_start( ap, cmd );
@@ -53,8 +54,10 @@ int fcntl(
else {
/* allocate a file control block */
diop = rtems_libio_allocate();
- if ( diop == 0 )
- return -1;
+ if ( diop == 0 ) {
+ ret = -1;
+ break;
+ }
}
diop->handlers = iop->handlers;
@@ -62,12 +65,11 @@ int fcntl(
diop->flags = iop->flags;
diop->pathinfo = iop->pathinfo;
- return 0;
+ break;
case F_GETFD: /* get f_flags */
- if ( iop->flags & LIBIO_FLAGS_CLOSE_ON_EXEC )
- return 1;
- return 0;
+ ret = ((iop->flags & LIBIO_FLAGS_CLOSE_ON_EXEC) != 0);
+ break;
case F_SETFD: /* set f_flags */
/*
@@ -82,46 +84,56 @@ int fcntl(
iop->flags |= LIBIO_FLAGS_CLOSE_ON_EXEC;
else
iop->flags &= ~LIBIO_FLAGS_CLOSE_ON_EXEC;
- return 0;
+ break;
case F_GETFL: /* more flags (cloexec) */
- return rtems_libio_to_fcntl_flags( iop->flags );
+ ret = rtems_libio_to_fcntl_flags( iop->flags );
case F_SETFL:
flags = rtems_libio_fcntl_flags( va_arg( ap, int ) );
/*
- * XXX Double check this in the POSIX spec. According to the Linux
- * XXX man page, only these flags can be added.
- */
-
- flags = (iop->flags & ~(O_APPEND|O_NONBLOCK)) |
- (flags & (O_APPEND|O_NONBLOCK));
-
- /*
* XXX If we are turning on append, should we seek to the end?
*/
- iop->flags = flags;
- return 0;
+ iop->flags = (iop->flags & ~(O_APPEND | O_NONBLOCK)) |
+ (flags & (O_APPEND | O_NONBLOCK));
+ break;
case F_GETLK:
- return -1;
+ errno = ENOTSUP;
+ ret = -1;
+ break;
case F_SETLK:
- return -1;
+ errno = ENOTSUP;
+ ret = -1;
+ break;
case F_SETLKW:
- return -1;
+ errno = ENOTSUP;
+ ret = -1;
+ break;
case F_SETOWN: /* for sockets. */
- return -1;
+ errno = ENOTSUP;
+ ret = -1;
+ break;
case F_GETOWN: /* for sockets. */
- return -1;
+ errno = ENOTSUP;
+ ret = -1;
+ break;
default:
break;
}
- return -1;
+ if ((ret >= 0) && iop->handlers->fcntl) {
+ int err = (*iop->handlers->fcntl)( cmd, iop );
+ if (err) {
+ errno = err;
+ ret = -1;
+ }
+ }
+ return ret;
}
diff --git a/c/src/exec/libnetworking/rtems/rtems_syscall.c b/c/src/exec/libnetworking/rtems/rtems_syscall.c
index 141b7ceeba..7797e46a2a 100644
--- a/c/src/exec/libnetworking/rtems/rtems_syscall.c
+++ b/c/src/exec/libnetworking/rtems/rtems_syscall.c
@@ -20,6 +20,7 @@
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/proc.h>
+#include <sys/fcntl.h>
#include <sys/filio.h>
#include <net/if.h>
@@ -644,14 +645,18 @@ rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, unsigned32 count)
}
static int
-so_ioctl (struct socket *so, unsigned32 command, void *buffer)
+so_ioctl (rtems_libio_t *iop, struct socket *so, unsigned32 command, void *buffer)
{
switch (command) {
case FIONBIO:
- if (*(int *)buffer)
+ if (*(int *)buffer) {
+ iop->flags |= O_NONBLOCK;
so->so_state |= SS_NBIO;
- else
+ }
+ else {
+ iop->flags &= ~O_NONBLOCK;
so->so_state &= ~SS_NBIO;
+ }
return 0;
case FIONREAD:
@@ -678,7 +683,7 @@ rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
rtems_bsdnet_semaphore_release ();
return -1;
}
- error = so_ioctl (so, command, buffer);
+ error = so_ioctl (iop, so, command, buffer);
rtems_bsdnet_semaphore_release ();
if (error) {
errno = error;
@@ -688,6 +693,26 @@ rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
}
static int
+rtems_bsdnet_fcntl (int cmd, rtems_libio_t *iop)
+{
+ struct socket *so;
+
+ if (cmd == F_SETFL) {
+ rtems_bsdnet_semaphore_obtain ();
+ if ((so = iop->data1) == NULL) {
+ rtems_bsdnet_semaphore_release ();
+ return EBADF;
+ }
+ if (iop->flags & O_NONBLOCK)
+ so->so_state |= SS_NBIO;
+ else
+ so->so_state &= ~SS_NBIO;
+ rtems_bsdnet_semaphore_release ();
+ }
+ return 0;
+}
+
+static int
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
{
sp->st_mode = S_IFSOCK;
@@ -707,4 +732,5 @@ static const rtems_filesystem_file_handlers_r socket_handlers = {
NULL, /* fpathconf */
NULL, /* fsync */
NULL, /* fdatasync */
+ rtems_bsdnet_fcntl, /* fcntl */
};
diff --git a/c/src/lib/include/rtems/libio.h b/c/src/lib/include/rtems/libio.h
index 1cbfef383b..6ded1e361d 100644
--- a/c/src/lib/include/rtems/libio.h
+++ b/c/src/lib/include/rtems/libio.h
@@ -115,6 +115,11 @@ typedef int (*rtems_filesystem_fdatasync_t)(
rtems_libio_t *iop
);
+typedef int (*rtems_filesystem_fcntl_t)(
+ int cmd,
+ rtems_libio_t *iop
+);
+
typedef struct {
rtems_filesystem_open_t open;
rtems_filesystem_close_t close;
@@ -128,6 +133,7 @@ typedef struct {
rtems_filesystem_fpathconf_t fpathconf;
rtems_filesystem_fsync_t fsync;
rtems_filesystem_fdatasync_t fdatasync;
+ rtems_filesystem_fcntl_t fcntl;
} rtems_filesystem_file_handlers_r;
/*
diff --git a/c/src/lib/libc/fcntl.c b/c/src/lib/libc/fcntl.c
index 381df45f26..3a65a74574 100644
--- a/c/src/lib/libc/fcntl.c
+++ b/c/src/lib/libc/fcntl.c
@@ -30,6 +30,7 @@ int fcntl(
rtems_libio_t *diop;
int fd2;
int flags;
+ int ret = 0;
va_start( ap, cmd );
@@ -53,8 +54,10 @@ int fcntl(
else {
/* allocate a file control block */
diop = rtems_libio_allocate();
- if ( diop == 0 )
- return -1;
+ if ( diop == 0 ) {
+ ret = -1;
+ break;
+ }
}
diop->handlers = iop->handlers;
@@ -62,12 +65,11 @@ int fcntl(
diop->flags = iop->flags;
diop->pathinfo = iop->pathinfo;
- return 0;
+ break;
case F_GETFD: /* get f_flags */
- if ( iop->flags & LIBIO_FLAGS_CLOSE_ON_EXEC )
- return 1;
- return 0;
+ ret = ((iop->flags & LIBIO_FLAGS_CLOSE_ON_EXEC) != 0);
+ break;
case F_SETFD: /* set f_flags */
/*
@@ -82,46 +84,56 @@ int fcntl(
iop->flags |= LIBIO_FLAGS_CLOSE_ON_EXEC;
else
iop->flags &= ~LIBIO_FLAGS_CLOSE_ON_EXEC;
- return 0;
+ break;
case F_GETFL: /* more flags (cloexec) */
- return rtems_libio_to_fcntl_flags( iop->flags );
+ ret = rtems_libio_to_fcntl_flags( iop->flags );
case F_SETFL:
flags = rtems_libio_fcntl_flags( va_arg( ap, int ) );
/*
- * XXX Double check this in the POSIX spec. According to the Linux
- * XXX man page, only these flags can be added.
- */
-
- flags = (iop->flags & ~(O_APPEND|O_NONBLOCK)) |
- (flags & (O_APPEND|O_NONBLOCK));
-
- /*
* XXX If we are turning on append, should we seek to the end?
*/
- iop->flags = flags;
- return 0;
+ iop->flags = (iop->flags & ~(O_APPEND | O_NONBLOCK)) |
+ (flags & (O_APPEND | O_NONBLOCK));
+ break;
case F_GETLK:
- return -1;
+ errno = ENOTSUP;
+ ret = -1;
+ break;
case F_SETLK:
- return -1;
+ errno = ENOTSUP;
+ ret = -1;
+ break;
case F_SETLKW:
- return -1;
+ errno = ENOTSUP;
+ ret = -1;
+ break;
case F_SETOWN: /* for sockets. */
- return -1;
+ errno = ENOTSUP;
+ ret = -1;
+ break;
case F_GETOWN: /* for sockets. */
- return -1;
+ errno = ENOTSUP;
+ ret = -1;
+ break;
default:
break;
}
- return -1;
+ if ((ret >= 0) && iop->handlers->fcntl) {
+ int err = (*iop->handlers->fcntl)( cmd, iop );
+ if (err) {
+ errno = err;
+ ret = -1;
+ }
+ }
+ return ret;
}
diff --git a/c/src/lib/libc/libio.h b/c/src/lib/libc/libio.h
index 1cbfef383b..6ded1e361d 100644
--- a/c/src/lib/libc/libio.h
+++ b/c/src/lib/libc/libio.h
@@ -115,6 +115,11 @@ typedef int (*rtems_filesystem_fdatasync_t)(
rtems_libio_t *iop
);
+typedef int (*rtems_filesystem_fcntl_t)(
+ int cmd,
+ rtems_libio_t *iop
+);
+
typedef struct {
rtems_filesystem_open_t open;
rtems_filesystem_close_t close;
@@ -128,6 +133,7 @@ typedef struct {
rtems_filesystem_fpathconf_t fpathconf;
rtems_filesystem_fsync_t fsync;
rtems_filesystem_fdatasync_t fdatasync;
+ rtems_filesystem_fcntl_t fcntl;
} rtems_filesystem_file_handlers_r;
/*
diff --git a/c/src/lib/libnetworking/rtems/rtems_syscall.c b/c/src/lib/libnetworking/rtems/rtems_syscall.c
index 141b7ceeba..7797e46a2a 100644
--- a/c/src/lib/libnetworking/rtems/rtems_syscall.c
+++ b/c/src/lib/libnetworking/rtems/rtems_syscall.c
@@ -20,6 +20,7 @@
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/proc.h>
+#include <sys/fcntl.h>
#include <sys/filio.h>
#include <net/if.h>
@@ -644,14 +645,18 @@ rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, unsigned32 count)
}
static int
-so_ioctl (struct socket *so, unsigned32 command, void *buffer)
+so_ioctl (rtems_libio_t *iop, struct socket *so, unsigned32 command, void *buffer)
{
switch (command) {
case FIONBIO:
- if (*(int *)buffer)
+ if (*(int *)buffer) {
+ iop->flags |= O_NONBLOCK;
so->so_state |= SS_NBIO;
- else
+ }
+ else {
+ iop->flags &= ~O_NONBLOCK;
so->so_state &= ~SS_NBIO;
+ }
return 0;
case FIONREAD:
@@ -678,7 +683,7 @@ rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
rtems_bsdnet_semaphore_release ();
return -1;
}
- error = so_ioctl (so, command, buffer);
+ error = so_ioctl (iop, so, command, buffer);
rtems_bsdnet_semaphore_release ();
if (error) {
errno = error;
@@ -688,6 +693,26 @@ rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
}
static int
+rtems_bsdnet_fcntl (int cmd, rtems_libio_t *iop)
+{
+ struct socket *so;
+
+ if (cmd == F_SETFL) {
+ rtems_bsdnet_semaphore_obtain ();
+ if ((so = iop->data1) == NULL) {
+ rtems_bsdnet_semaphore_release ();
+ return EBADF;
+ }
+ if (iop->flags & O_NONBLOCK)
+ so->so_state |= SS_NBIO;
+ else
+ so->so_state &= ~SS_NBIO;
+ rtems_bsdnet_semaphore_release ();
+ }
+ return 0;
+}
+
+static int
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
{
sp->st_mode = S_IFSOCK;
@@ -707,4 +732,5 @@ static const rtems_filesystem_file_handlers_r socket_handlers = {
NULL, /* fpathconf */
NULL, /* fsync */
NULL, /* fdatasync */
+ rtems_bsdnet_fcntl, /* fcntl */
};
diff --git a/c/src/libnetworking/rtems/rtems_syscall.c b/c/src/libnetworking/rtems/rtems_syscall.c
index 141b7ceeba..7797e46a2a 100644
--- a/c/src/libnetworking/rtems/rtems_syscall.c
+++ b/c/src/libnetworking/rtems/rtems_syscall.c
@@ -20,6 +20,7 @@
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/proc.h>
+#include <sys/fcntl.h>
#include <sys/filio.h>
#include <net/if.h>
@@ -644,14 +645,18 @@ rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, unsigned32 count)
}
static int
-so_ioctl (struct socket *so, unsigned32 command, void *buffer)
+so_ioctl (rtems_libio_t *iop, struct socket *so, unsigned32 command, void *buffer)
{
switch (command) {
case FIONBIO:
- if (*(int *)buffer)
+ if (*(int *)buffer) {
+ iop->flags |= O_NONBLOCK;
so->so_state |= SS_NBIO;
- else
+ }
+ else {
+ iop->flags &= ~O_NONBLOCK;
so->so_state &= ~SS_NBIO;
+ }
return 0;
case FIONREAD:
@@ -678,7 +683,7 @@ rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
rtems_bsdnet_semaphore_release ();
return -1;
}
- error = so_ioctl (so, command, buffer);
+ error = so_ioctl (iop, so, command, buffer);
rtems_bsdnet_semaphore_release ();
if (error) {
errno = error;
@@ -688,6 +693,26 @@ rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
}
static int
+rtems_bsdnet_fcntl (int cmd, rtems_libio_t *iop)
+{
+ struct socket *so;
+
+ if (cmd == F_SETFL) {
+ rtems_bsdnet_semaphore_obtain ();
+ if ((so = iop->data1) == NULL) {
+ rtems_bsdnet_semaphore_release ();
+ return EBADF;
+ }
+ if (iop->flags & O_NONBLOCK)
+ so->so_state |= SS_NBIO;
+ else
+ so->so_state &= ~SS_NBIO;
+ rtems_bsdnet_semaphore_release ();
+ }
+ return 0;
+}
+
+static int
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
{
sp->st_mode = S_IFSOCK;
@@ -707,4 +732,5 @@ static const rtems_filesystem_file_handlers_r socket_handlers = {
NULL, /* fpathconf */
NULL, /* fsync */
NULL, /* fdatasync */
+ rtems_bsdnet_fcntl, /* fcntl */
};