forked from Imagelibrary/rtems
Patch from Eric Norum <eric@skatter.usask.ca> that adds external
fcntl support and an external fcntl handler for sockets.
This commit is contained in:
@@ -115,6 +115,11 @@ typedef int (*rtems_filesystem_fdatasync_t)(
|
|||||||
rtems_libio_t *iop
|
rtems_libio_t *iop
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef int (*rtems_filesystem_fcntl_t)(
|
||||||
|
int cmd,
|
||||||
|
rtems_libio_t *iop
|
||||||
|
);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
rtems_filesystem_open_t open;
|
rtems_filesystem_open_t open;
|
||||||
rtems_filesystem_close_t close;
|
rtems_filesystem_close_t close;
|
||||||
@@ -128,6 +133,7 @@ typedef struct {
|
|||||||
rtems_filesystem_fpathconf_t fpathconf;
|
rtems_filesystem_fpathconf_t fpathconf;
|
||||||
rtems_filesystem_fsync_t fsync;
|
rtems_filesystem_fsync_t fsync;
|
||||||
rtems_filesystem_fdatasync_t fdatasync;
|
rtems_filesystem_fdatasync_t fdatasync;
|
||||||
|
rtems_filesystem_fcntl_t fcntl;
|
||||||
} rtems_filesystem_file_handlers_r;
|
} rtems_filesystem_file_handlers_r;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ int fcntl(
|
|||||||
rtems_libio_t *diop;
|
rtems_libio_t *diop;
|
||||||
int fd2;
|
int fd2;
|
||||||
int flags;
|
int flags;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
va_start( ap, cmd );
|
va_start( ap, cmd );
|
||||||
|
|
||||||
@@ -53,8 +54,10 @@ int fcntl(
|
|||||||
else {
|
else {
|
||||||
/* allocate a file control block */
|
/* allocate a file control block */
|
||||||
diop = rtems_libio_allocate();
|
diop = rtems_libio_allocate();
|
||||||
if ( diop == 0 )
|
if ( diop == 0 ) {
|
||||||
return -1;
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
diop->handlers = iop->handlers;
|
diop->handlers = iop->handlers;
|
||||||
@@ -62,12 +65,11 @@ int fcntl(
|
|||||||
diop->flags = iop->flags;
|
diop->flags = iop->flags;
|
||||||
diop->pathinfo = iop->pathinfo;
|
diop->pathinfo = iop->pathinfo;
|
||||||
|
|
||||||
return 0;
|
break;
|
||||||
|
|
||||||
case F_GETFD: /* get f_flags */
|
case F_GETFD: /* get f_flags */
|
||||||
if ( iop->flags & LIBIO_FLAGS_CLOSE_ON_EXEC )
|
ret = ((iop->flags & LIBIO_FLAGS_CLOSE_ON_EXEC) != 0);
|
||||||
return 1;
|
break;
|
||||||
return 0;
|
|
||||||
|
|
||||||
case F_SETFD: /* set f_flags */
|
case F_SETFD: /* set f_flags */
|
||||||
/*
|
/*
|
||||||
@@ -82,46 +84,56 @@ int fcntl(
|
|||||||
iop->flags |= LIBIO_FLAGS_CLOSE_ON_EXEC;
|
iop->flags |= LIBIO_FLAGS_CLOSE_ON_EXEC;
|
||||||
else
|
else
|
||||||
iop->flags &= ~LIBIO_FLAGS_CLOSE_ON_EXEC;
|
iop->flags &= ~LIBIO_FLAGS_CLOSE_ON_EXEC;
|
||||||
return 0;
|
break;
|
||||||
|
|
||||||
case F_GETFL: /* more flags (cloexec) */
|
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:
|
case F_SETFL:
|
||||||
flags = rtems_libio_fcntl_flags( va_arg( ap, int ) );
|
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?
|
* XXX If we are turning on append, should we seek to the end?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
iop->flags = flags;
|
iop->flags = (iop->flags & ~(O_APPEND | O_NONBLOCK)) |
|
||||||
return 0;
|
(flags & (O_APPEND | O_NONBLOCK));
|
||||||
|
break;
|
||||||
|
|
||||||
case F_GETLK:
|
case F_GETLK:
|
||||||
return -1;
|
errno = ENOTSUP;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case F_SETLK:
|
case F_SETLK:
|
||||||
return -1;
|
errno = ENOTSUP;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case F_SETLKW:
|
case F_SETLKW:
|
||||||
return -1;
|
errno = ENOTSUP;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case F_SETOWN: /* for sockets. */
|
case F_SETOWN: /* for sockets. */
|
||||||
return -1;
|
errno = ENOTSUP;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case F_GETOWN: /* for sockets. */
|
case F_GETOWN: /* for sockets. */
|
||||||
return -1;
|
errno = ENOTSUP;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return -1;
|
if ((ret >= 0) && iop->handlers->fcntl) {
|
||||||
|
int err = (*iop->handlers->fcntl)( cmd, iop );
|
||||||
|
if (err) {
|
||||||
|
errno = err;
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <sys/socketvar.h>
|
#include <sys/socketvar.h>
|
||||||
#include <sys/protosw.h>
|
#include <sys/protosw.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
#include <sys/filio.h>
|
#include <sys/filio.h>
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
@@ -644,14 +645,18 @@ rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, unsigned32 count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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) {
|
switch (command) {
|
||||||
case FIONBIO:
|
case FIONBIO:
|
||||||
if (*(int *)buffer)
|
if (*(int *)buffer) {
|
||||||
|
iop->flags |= O_NONBLOCK;
|
||||||
so->so_state |= SS_NBIO;
|
so->so_state |= SS_NBIO;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
|
iop->flags &= ~O_NONBLOCK;
|
||||||
so->so_state &= ~SS_NBIO;
|
so->so_state &= ~SS_NBIO;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case FIONREAD:
|
case FIONREAD:
|
||||||
@@ -678,7 +683,7 @@ rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
|
|||||||
rtems_bsdnet_semaphore_release ();
|
rtems_bsdnet_semaphore_release ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
error = so_ioctl (so, command, buffer);
|
error = so_ioctl (iop, so, command, buffer);
|
||||||
rtems_bsdnet_semaphore_release ();
|
rtems_bsdnet_semaphore_release ();
|
||||||
if (error) {
|
if (error) {
|
||||||
errno = error;
|
errno = error;
|
||||||
@@ -687,6 +692,26 @@ rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static int
|
||||||
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
|
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
|
||||||
{
|
{
|
||||||
@@ -707,4 +732,5 @@ static const rtems_filesystem_file_handlers_r socket_handlers = {
|
|||||||
NULL, /* fpathconf */
|
NULL, /* fpathconf */
|
||||||
NULL, /* fsync */
|
NULL, /* fsync */
|
||||||
NULL, /* fdatasync */
|
NULL, /* fdatasync */
|
||||||
|
rtems_bsdnet_fcntl, /* fcntl */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -115,6 +115,11 @@ typedef int (*rtems_filesystem_fdatasync_t)(
|
|||||||
rtems_libio_t *iop
|
rtems_libio_t *iop
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef int (*rtems_filesystem_fcntl_t)(
|
||||||
|
int cmd,
|
||||||
|
rtems_libio_t *iop
|
||||||
|
);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
rtems_filesystem_open_t open;
|
rtems_filesystem_open_t open;
|
||||||
rtems_filesystem_close_t close;
|
rtems_filesystem_close_t close;
|
||||||
@@ -128,6 +133,7 @@ typedef struct {
|
|||||||
rtems_filesystem_fpathconf_t fpathconf;
|
rtems_filesystem_fpathconf_t fpathconf;
|
||||||
rtems_filesystem_fsync_t fsync;
|
rtems_filesystem_fsync_t fsync;
|
||||||
rtems_filesystem_fdatasync_t fdatasync;
|
rtems_filesystem_fdatasync_t fdatasync;
|
||||||
|
rtems_filesystem_fcntl_t fcntl;
|
||||||
} rtems_filesystem_file_handlers_r;
|
} rtems_filesystem_file_handlers_r;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ int fcntl(
|
|||||||
rtems_libio_t *diop;
|
rtems_libio_t *diop;
|
||||||
int fd2;
|
int fd2;
|
||||||
int flags;
|
int flags;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
va_start( ap, cmd );
|
va_start( ap, cmd );
|
||||||
|
|
||||||
@@ -53,8 +54,10 @@ int fcntl(
|
|||||||
else {
|
else {
|
||||||
/* allocate a file control block */
|
/* allocate a file control block */
|
||||||
diop = rtems_libio_allocate();
|
diop = rtems_libio_allocate();
|
||||||
if ( diop == 0 )
|
if ( diop == 0 ) {
|
||||||
return -1;
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
diop->handlers = iop->handlers;
|
diop->handlers = iop->handlers;
|
||||||
@@ -62,12 +65,11 @@ int fcntl(
|
|||||||
diop->flags = iop->flags;
|
diop->flags = iop->flags;
|
||||||
diop->pathinfo = iop->pathinfo;
|
diop->pathinfo = iop->pathinfo;
|
||||||
|
|
||||||
return 0;
|
break;
|
||||||
|
|
||||||
case F_GETFD: /* get f_flags */
|
case F_GETFD: /* get f_flags */
|
||||||
if ( iop->flags & LIBIO_FLAGS_CLOSE_ON_EXEC )
|
ret = ((iop->flags & LIBIO_FLAGS_CLOSE_ON_EXEC) != 0);
|
||||||
return 1;
|
break;
|
||||||
return 0;
|
|
||||||
|
|
||||||
case F_SETFD: /* set f_flags */
|
case F_SETFD: /* set f_flags */
|
||||||
/*
|
/*
|
||||||
@@ -82,46 +84,56 @@ int fcntl(
|
|||||||
iop->flags |= LIBIO_FLAGS_CLOSE_ON_EXEC;
|
iop->flags |= LIBIO_FLAGS_CLOSE_ON_EXEC;
|
||||||
else
|
else
|
||||||
iop->flags &= ~LIBIO_FLAGS_CLOSE_ON_EXEC;
|
iop->flags &= ~LIBIO_FLAGS_CLOSE_ON_EXEC;
|
||||||
return 0;
|
break;
|
||||||
|
|
||||||
case F_GETFL: /* more flags (cloexec) */
|
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:
|
case F_SETFL:
|
||||||
flags = rtems_libio_fcntl_flags( va_arg( ap, int ) );
|
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?
|
* XXX If we are turning on append, should we seek to the end?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
iop->flags = flags;
|
iop->flags = (iop->flags & ~(O_APPEND | O_NONBLOCK)) |
|
||||||
return 0;
|
(flags & (O_APPEND | O_NONBLOCK));
|
||||||
|
break;
|
||||||
|
|
||||||
case F_GETLK:
|
case F_GETLK:
|
||||||
return -1;
|
errno = ENOTSUP;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case F_SETLK:
|
case F_SETLK:
|
||||||
return -1;
|
errno = ENOTSUP;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case F_SETLKW:
|
case F_SETLKW:
|
||||||
return -1;
|
errno = ENOTSUP;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case F_SETOWN: /* for sockets. */
|
case F_SETOWN: /* for sockets. */
|
||||||
return -1;
|
errno = ENOTSUP;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case F_GETOWN: /* for sockets. */
|
case F_GETOWN: /* for sockets. */
|
||||||
return -1;
|
errno = ENOTSUP;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return -1;
|
if ((ret >= 0) && iop->handlers->fcntl) {
|
||||||
|
int err = (*iop->handlers->fcntl)( cmd, iop );
|
||||||
|
if (err) {
|
||||||
|
errno = err;
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,6 +115,11 @@ typedef int (*rtems_filesystem_fdatasync_t)(
|
|||||||
rtems_libio_t *iop
|
rtems_libio_t *iop
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef int (*rtems_filesystem_fcntl_t)(
|
||||||
|
int cmd,
|
||||||
|
rtems_libio_t *iop
|
||||||
|
);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
rtems_filesystem_open_t open;
|
rtems_filesystem_open_t open;
|
||||||
rtems_filesystem_close_t close;
|
rtems_filesystem_close_t close;
|
||||||
@@ -128,6 +133,7 @@ typedef struct {
|
|||||||
rtems_filesystem_fpathconf_t fpathconf;
|
rtems_filesystem_fpathconf_t fpathconf;
|
||||||
rtems_filesystem_fsync_t fsync;
|
rtems_filesystem_fsync_t fsync;
|
||||||
rtems_filesystem_fdatasync_t fdatasync;
|
rtems_filesystem_fdatasync_t fdatasync;
|
||||||
|
rtems_filesystem_fcntl_t fcntl;
|
||||||
} rtems_filesystem_file_handlers_r;
|
} rtems_filesystem_file_handlers_r;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <sys/socketvar.h>
|
#include <sys/socketvar.h>
|
||||||
#include <sys/protosw.h>
|
#include <sys/protosw.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
#include <sys/filio.h>
|
#include <sys/filio.h>
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
@@ -644,14 +645,18 @@ rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, unsigned32 count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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) {
|
switch (command) {
|
||||||
case FIONBIO:
|
case FIONBIO:
|
||||||
if (*(int *)buffer)
|
if (*(int *)buffer) {
|
||||||
|
iop->flags |= O_NONBLOCK;
|
||||||
so->so_state |= SS_NBIO;
|
so->so_state |= SS_NBIO;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
|
iop->flags &= ~O_NONBLOCK;
|
||||||
so->so_state &= ~SS_NBIO;
|
so->so_state &= ~SS_NBIO;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case FIONREAD:
|
case FIONREAD:
|
||||||
@@ -678,7 +683,7 @@ rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
|
|||||||
rtems_bsdnet_semaphore_release ();
|
rtems_bsdnet_semaphore_release ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
error = so_ioctl (so, command, buffer);
|
error = so_ioctl (iop, so, command, buffer);
|
||||||
rtems_bsdnet_semaphore_release ();
|
rtems_bsdnet_semaphore_release ();
|
||||||
if (error) {
|
if (error) {
|
||||||
errno = error;
|
errno = error;
|
||||||
@@ -687,6 +692,26 @@ rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static int
|
||||||
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
|
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
|
||||||
{
|
{
|
||||||
@@ -707,4 +732,5 @@ static const rtems_filesystem_file_handlers_r socket_handlers = {
|
|||||||
NULL, /* fpathconf */
|
NULL, /* fpathconf */
|
||||||
NULL, /* fsync */
|
NULL, /* fsync */
|
||||||
NULL, /* fdatasync */
|
NULL, /* fdatasync */
|
||||||
|
rtems_bsdnet_fcntl, /* fcntl */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <sys/socketvar.h>
|
#include <sys/socketvar.h>
|
||||||
#include <sys/protosw.h>
|
#include <sys/protosw.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
#include <sys/filio.h>
|
#include <sys/filio.h>
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
@@ -644,14 +645,18 @@ rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, unsigned32 count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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) {
|
switch (command) {
|
||||||
case FIONBIO:
|
case FIONBIO:
|
||||||
if (*(int *)buffer)
|
if (*(int *)buffer) {
|
||||||
|
iop->flags |= O_NONBLOCK;
|
||||||
so->so_state |= SS_NBIO;
|
so->so_state |= SS_NBIO;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
|
iop->flags &= ~O_NONBLOCK;
|
||||||
so->so_state &= ~SS_NBIO;
|
so->so_state &= ~SS_NBIO;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case FIONREAD:
|
case FIONREAD:
|
||||||
@@ -678,7 +683,7 @@ rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
|
|||||||
rtems_bsdnet_semaphore_release ();
|
rtems_bsdnet_semaphore_release ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
error = so_ioctl (so, command, buffer);
|
error = so_ioctl (iop, so, command, buffer);
|
||||||
rtems_bsdnet_semaphore_release ();
|
rtems_bsdnet_semaphore_release ();
|
||||||
if (error) {
|
if (error) {
|
||||||
errno = error;
|
errno = error;
|
||||||
@@ -687,6 +692,26 @@ rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static int
|
||||||
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
|
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
|
||||||
{
|
{
|
||||||
@@ -707,4 +732,5 @@ static const rtems_filesystem_file_handlers_r socket_handlers = {
|
|||||||
NULL, /* fpathconf */
|
NULL, /* fpathconf */
|
||||||
NULL, /* fsync */
|
NULL, /* fsync */
|
||||||
NULL, /* fdatasync */
|
NULL, /* fdatasync */
|
||||||
|
rtems_bsdnet_fcntl, /* fcntl */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -115,6 +115,11 @@ typedef int (*rtems_filesystem_fdatasync_t)(
|
|||||||
rtems_libio_t *iop
|
rtems_libio_t *iop
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef int (*rtems_filesystem_fcntl_t)(
|
||||||
|
int cmd,
|
||||||
|
rtems_libio_t *iop
|
||||||
|
);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
rtems_filesystem_open_t open;
|
rtems_filesystem_open_t open;
|
||||||
rtems_filesystem_close_t close;
|
rtems_filesystem_close_t close;
|
||||||
@@ -128,6 +133,7 @@ typedef struct {
|
|||||||
rtems_filesystem_fpathconf_t fpathconf;
|
rtems_filesystem_fpathconf_t fpathconf;
|
||||||
rtems_filesystem_fsync_t fsync;
|
rtems_filesystem_fsync_t fsync;
|
||||||
rtems_filesystem_fdatasync_t fdatasync;
|
rtems_filesystem_fdatasync_t fdatasync;
|
||||||
|
rtems_filesystem_fcntl_t fcntl;
|
||||||
} rtems_filesystem_file_handlers_r;
|
} rtems_filesystem_file_handlers_r;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ int fcntl(
|
|||||||
rtems_libio_t *diop;
|
rtems_libio_t *diop;
|
||||||
int fd2;
|
int fd2;
|
||||||
int flags;
|
int flags;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
va_start( ap, cmd );
|
va_start( ap, cmd );
|
||||||
|
|
||||||
@@ -53,8 +54,10 @@ int fcntl(
|
|||||||
else {
|
else {
|
||||||
/* allocate a file control block */
|
/* allocate a file control block */
|
||||||
diop = rtems_libio_allocate();
|
diop = rtems_libio_allocate();
|
||||||
if ( diop == 0 )
|
if ( diop == 0 ) {
|
||||||
return -1;
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
diop->handlers = iop->handlers;
|
diop->handlers = iop->handlers;
|
||||||
@@ -62,12 +65,11 @@ int fcntl(
|
|||||||
diop->flags = iop->flags;
|
diop->flags = iop->flags;
|
||||||
diop->pathinfo = iop->pathinfo;
|
diop->pathinfo = iop->pathinfo;
|
||||||
|
|
||||||
return 0;
|
break;
|
||||||
|
|
||||||
case F_GETFD: /* get f_flags */
|
case F_GETFD: /* get f_flags */
|
||||||
if ( iop->flags & LIBIO_FLAGS_CLOSE_ON_EXEC )
|
ret = ((iop->flags & LIBIO_FLAGS_CLOSE_ON_EXEC) != 0);
|
||||||
return 1;
|
break;
|
||||||
return 0;
|
|
||||||
|
|
||||||
case F_SETFD: /* set f_flags */
|
case F_SETFD: /* set f_flags */
|
||||||
/*
|
/*
|
||||||
@@ -82,46 +84,56 @@ int fcntl(
|
|||||||
iop->flags |= LIBIO_FLAGS_CLOSE_ON_EXEC;
|
iop->flags |= LIBIO_FLAGS_CLOSE_ON_EXEC;
|
||||||
else
|
else
|
||||||
iop->flags &= ~LIBIO_FLAGS_CLOSE_ON_EXEC;
|
iop->flags &= ~LIBIO_FLAGS_CLOSE_ON_EXEC;
|
||||||
return 0;
|
break;
|
||||||
|
|
||||||
case F_GETFL: /* more flags (cloexec) */
|
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:
|
case F_SETFL:
|
||||||
flags = rtems_libio_fcntl_flags( va_arg( ap, int ) );
|
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?
|
* XXX If we are turning on append, should we seek to the end?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
iop->flags = flags;
|
iop->flags = (iop->flags & ~(O_APPEND | O_NONBLOCK)) |
|
||||||
return 0;
|
(flags & (O_APPEND | O_NONBLOCK));
|
||||||
|
break;
|
||||||
|
|
||||||
case F_GETLK:
|
case F_GETLK:
|
||||||
return -1;
|
errno = ENOTSUP;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case F_SETLK:
|
case F_SETLK:
|
||||||
return -1;
|
errno = ENOTSUP;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case F_SETLKW:
|
case F_SETLKW:
|
||||||
return -1;
|
errno = ENOTSUP;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case F_SETOWN: /* for sockets. */
|
case F_SETOWN: /* for sockets. */
|
||||||
return -1;
|
errno = ENOTSUP;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case F_GETOWN: /* for sockets. */
|
case F_GETOWN: /* for sockets. */
|
||||||
return -1;
|
errno = ENOTSUP;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return -1;
|
if ((ret >= 0) && iop->handlers->fcntl) {
|
||||||
|
int err = (*iop->handlers->fcntl)( cmd, iop );
|
||||||
|
if (err) {
|
||||||
|
errno = err;
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <sys/socketvar.h>
|
#include <sys/socketvar.h>
|
||||||
#include <sys/protosw.h>
|
#include <sys/protosw.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
#include <sys/filio.h>
|
#include <sys/filio.h>
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
@@ -644,14 +645,18 @@ rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, unsigned32 count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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) {
|
switch (command) {
|
||||||
case FIONBIO:
|
case FIONBIO:
|
||||||
if (*(int *)buffer)
|
if (*(int *)buffer) {
|
||||||
|
iop->flags |= O_NONBLOCK;
|
||||||
so->so_state |= SS_NBIO;
|
so->so_state |= SS_NBIO;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
|
iop->flags &= ~O_NONBLOCK;
|
||||||
so->so_state &= ~SS_NBIO;
|
so->so_state &= ~SS_NBIO;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case FIONREAD:
|
case FIONREAD:
|
||||||
@@ -678,7 +683,7 @@ rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
|
|||||||
rtems_bsdnet_semaphore_release ();
|
rtems_bsdnet_semaphore_release ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
error = so_ioctl (so, command, buffer);
|
error = so_ioctl (iop, so, command, buffer);
|
||||||
rtems_bsdnet_semaphore_release ();
|
rtems_bsdnet_semaphore_release ();
|
||||||
if (error) {
|
if (error) {
|
||||||
errno = error;
|
errno = error;
|
||||||
@@ -687,6 +692,26 @@ rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static int
|
||||||
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
|
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
|
||||||
{
|
{
|
||||||
@@ -707,4 +732,5 @@ static const rtems_filesystem_file_handlers_r socket_handlers = {
|
|||||||
NULL, /* fpathconf */
|
NULL, /* fpathconf */
|
||||||
NULL, /* fsync */
|
NULL, /* fsync */
|
||||||
NULL, /* fdatasync */
|
NULL, /* fdatasync */
|
||||||
|
rtems_bsdnet_fcntl, /* fcntl */
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user