Patch from Eric Norum <eric@skatter.usask.ca> to eliminate external

IO handlers scheme that was implemented originally just to support
sockets.  The file system IO switch is more general and works fine.
This commit is contained in:
Joel Sherrill
1999-03-01 22:40:08 +00:00
parent e069cdc3f1
commit 73f6236bc0
68 changed files with 218 additions and 887 deletions

View File

@@ -67,15 +67,6 @@ extern rtems_libio_t *rtems_libio_iops;
extern rtems_libio_t *rtems_libio_last_iop; extern rtems_libio_t *rtems_libio_last_iop;
extern rtems_libio_t *rtems_libio_iop_freelist; extern rtems_libio_t *rtems_libio_iop_freelist;
/*
* External I/O Handlers Table
*
* Space for all possible handlers is preallocated
* to speed up dispatch to external handlers.
*/
extern rtems_libio_handler_t rtems_libio_handlers[15];
/* /*
* Default mode for all files. * Default mode for all files.
*/ */

View File

@@ -397,15 +397,8 @@ typedef struct {
#define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */ #define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */
#define LIBIO_FLAGS_CREATE 0x0400 /* create file */ #define LIBIO_FLAGS_CREATE 0x0400 /* create file */
#define LIBIO_FLAGS_CLOSE_ON_EXEC 0x0800 /* close on process exec() */ #define LIBIO_FLAGS_CLOSE_ON_EXEC 0x0800 /* close on process exec() */
#define LIBIO_FLAGS_HANDLER_SHIFT 12
#define LIBIO_FLAGS_HANDLER_MASK 0xF000 /* mask for external handler type */
#define LIBIO_FLAGS_HANDLER_RTEMS 0x0000 /* `traditional' RTEMS I/O */
#define LIBIO_FLAGS_HANDLER_SOCK 0x1000 /* BSD socket */
#define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE) #define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE)
void rtems_libio_init(void); void rtems_libio_init(void);
/* /*
@@ -446,35 +439,6 @@ typedef int (*rtems_libio_lseek_t)(
int whence int whence
); );
typedef struct {
rtems_libio_open_t open;
rtems_libio_close_t close;
rtems_libio_read_t read;
rtems_libio_write_t write;
rtems_libio_ioctl_t ioctl;
rtems_libio_lseek_t lseek;
} rtems_libio_handler_t;
/*
* Register a set of external handlers
*/
void rtems_register_libio_handler(
int handler_flag,
const rtems_libio_handler_t *handler
);
/*
* Macros to assist in management of external IO handlers.
*/
#define RTEMS_FILE_DESCRIPTOR_TYPE_FILE 0x0000
#define RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET 0x1000
#define rtems_make_file_descriptor(fd,flags) ((fd)|(flags))
#define rtems_file_descriptor_base(fd) ((fd) & 0x0FFF)
#define rtems_file_descriptor_type(fd) ((fd) & 0xF000)
#define rtems_file_descriptor_type_index(fd) ((((fd) & 0xF000) >> 12) - 1)
/* /*
* IOCTL values * IOCTL values
*/ */

View File

@@ -67,15 +67,6 @@ extern rtems_libio_t *rtems_libio_iops;
extern rtems_libio_t *rtems_libio_last_iop; extern rtems_libio_t *rtems_libio_last_iop;
extern rtems_libio_t *rtems_libio_iop_freelist; extern rtems_libio_t *rtems_libio_iop_freelist;
/*
* External I/O Handlers Table
*
* Space for all possible handlers is preallocated
* to speed up dispatch to external handlers.
*/
extern rtems_libio_handler_t rtems_libio_handlers[15];
/* /*
* Default mode for all files. * Default mode for all files.
*/ */

View File

@@ -20,35 +20,17 @@ int close(
{ {
rtems_libio_t *iop; rtems_libio_t *iop;
rtems_status_code rc; rtems_status_code rc;
int status;
rtems_libio_check_fd(fd); rtems_libio_check_fd(fd);
iop = rtems_libio_iop(fd); iop = rtems_libio_iop(fd);
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) {
int (*fp)(int fd);
fp = rtems_libio_handlers[ rc = RTEMS_SUCCESSFUL;
(iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].close; if ( iop->handlers->close )
if ( fp == NULL ) rc = (*iop->handlers->close)( iop );
set_errno_and_return_minus_one( EBADF );
status = (*fp)( fd );
return status;
}
if ( !iop->handlers )
set_errno_and_return_minus_one( EBADF );
if ( !iop->handlers->close )
set_errno_and_return_minus_one( ENOTSUP );
rc = (*iop->handlers->close)( iop );
rtems_libio_free( iop ); rtems_libio_free( iop );
if (rc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one( rc );
return rc; return rc;
} }

View File

@@ -31,13 +31,6 @@ int fchmod(
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* If this is not a file system based entity, it is an error.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the fchmod(). * Now process the fchmod().
*/ */

View File

@@ -36,13 +36,6 @@ int fcntl(
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* If this is not a file system based entity, it is an error.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the fcntl(). * Now process the fcntl().
*/ */

View File

@@ -27,14 +27,6 @@ int fdatasync(
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the fdatasync(). * Now process the fdatasync().
*/ */

View File

@@ -31,15 +31,6 @@ long fpathconf(
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ); rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ);
/*
* If this file descriptor is mapped to an external set of handlers,
* then it is an error since fpathconf() is not included in the
* set.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the information request. * Now process the information request.
*/ */

View File

@@ -32,34 +32,6 @@ int fstat(
if ( !sbuf ) if ( !sbuf )
set_errno_and_return_minus_one( EFAULT ); set_errno_and_return_minus_one( EFAULT );
/*
* Zero out the stat structure so the various support
* versions of stat don't have to.
*/
memset( sbuf, 0, sizeof(struct stat) );
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if (rtems_file_descriptor_type(fd)) {
switch (rtems_file_descriptor_type (fd)) {
case RTEMS_FILE_DESCRIPTOR_TYPE_FILE:
break;
case RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET:
#if !defined(__GO32__)
sbuf->st_mode = S_IFSOCK;
break;
#endif
default:
set_errno_and_return_minus_one( EBADF );
}
}
/* /*
* Now process the stat() request. * Now process the stat() request.
*/ */
@@ -68,9 +40,18 @@ int fstat(
rtems_libio_check_fd( fd ); rtems_libio_check_fd( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
if ( !iop->handlers )
set_errno_and_return_minus_one( EBADF );
if ( !iop->handlers->fstat ) if ( !iop->handlers->fstat )
set_errno_and_return_minus_one( ENOTSUP ); set_errno_and_return_minus_one( ENOTSUP );
/*
* Zero out the stat structure so the various support
* versions of stat don't have to.
*/
memset( sbuf, 0, sizeof(struct stat) );
return (*iop->handlers->fstat)( &iop->pathinfo, sbuf ); return (*iop->handlers->fstat)( &iop->pathinfo, sbuf );
} }

View File

@@ -27,14 +27,6 @@ int fsync(
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the fsync(). * Now process the fsync().
*/ */

View File

@@ -29,13 +29,6 @@ int ftruncate(
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* If this is not a file system based entity, it is an error.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the ftruncate() request. * Now process the ftruncate() request.
*/ */

View File

@@ -30,22 +30,6 @@ int ioctl(
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) {
rtems_libio_ioctl_t fp;
fp = rtems_libio_handlers[
(iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].ioctl;
if ( fp == NULL )
set_errno_and_return_minus_one( EBADF );
return (*fp)( fd, command, buffer );
}
/* /*
* Now process the ioctl(). * Now process the ioctl().
*/ */

View File

@@ -49,44 +49,12 @@ rtems_libio_t *rtems_libio_iops;
rtems_libio_t *rtems_libio_last_iop; rtems_libio_t *rtems_libio_last_iop;
rtems_libio_t *rtems_libio_iop_freelist; rtems_libio_t *rtems_libio_iop_freelist;
/*
* External I/O Handlers Table
*
* Space for all possible handlers is preallocated
* to speed up dispatch to external handlers.
*/
rtems_libio_handler_t rtems_libio_handlers[15];
/* /*
* Default mode for all files. * Default mode for all files.
*/ */
mode_t rtems_filesystem_umask; mode_t rtems_filesystem_umask;
/*
* rtems_register_libio_handler
*
* This function registers an external IO handler set. This lets
* other subsystems have their own versions of many of the system
* calls. For example, the networking code registers handlers which
* map the system calls for read() and write() to socket calls.
*
*/
void rtems_register_libio_handler(
int handler_flag,
const rtems_libio_handler_t *handler
)
{
int handler_index = (handler_flag >> LIBIO_FLAGS_HANDLER_SHIFT) - 1;
if ((handler_index < 0) || (handler_index >= 15))
rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER );
rtems_libio_handlers[handler_index] = *handler;
}
/* /*
* rtems_libio_init * rtems_libio_init
* *

View File

@@ -18,7 +18,6 @@
#include <errno.h> #include <errno.h>
/* /*
* Convert an RTEMS file descriptor to a BSD socket pointer. * Convert an RTEMS file descriptor to a BSD socket pointer.
*/ */
@@ -29,11 +28,13 @@ struct socket *rtems_bsdnet_fdToSocket(
{ {
rtems_libio_t *iop; rtems_libio_t *iop;
if ((unsigned32)fd >= rtems_libio_number_iops) if ((unsigned32)fd >= rtems_libio_number_iops) {
return NULL; errno = EBADF;
return NULL;
}
iop = &rtems_libio_iops[fd]; iop = &rtems_libio_iops[fd];
if ((iop->flags & LIBIO_FLAGS_HANDLER_MASK) != LIBIO_FLAGS_HANDLER_SOCK) if (iop->data1 == NULL)
return NULL; errno = EBADF;
return iop->data1; return iop->data1;
} }
@@ -42,17 +43,22 @@ struct socket *rtems_bsdnet_fdToSocket(
*/ */
int rtems_bsdnet_makeFdForSocket( int rtems_bsdnet_makeFdForSocket(
void *so void *so,
const rtems_filesystem_file_handlers_r *h
) )
{ {
rtems_libio_t *iop; rtems_libio_t *iop;
int fd;
iop = rtems_libio_allocate(); iop = rtems_libio_allocate();
if (iop == 0) { if (iop == 0) {
errno = ENFILE; errno = ENFILE;
return -1; return -1;
} }
iop->flags |= LIBIO_FLAGS_HANDLER_SOCK | LIBIO_FLAGS_WRITE | LIBIO_FLAGS_READ; fd = iop - rtems_libio_iops;
iop->flags |= LIBIO_FLAGS_WRITE | LIBIO_FLAGS_READ;
iop->data0 = fd;
iop->data1 = so; iop->data1 = so;
return iop - rtems_libio_iops; iop->handlers = h;
return fd;
} }

View File

@@ -28,22 +28,6 @@ off_t lseek(
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) {
rtems_libio_lseek_t fp;
fp = rtems_libio_handlers[
(iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].lseek;
if ( fp == NULL )
set_errno_and_return_minus_one( EBADF );
return (*fp)( fd, offset, whence );
}
/* /*
* Now process the lseek(). * Now process the lseek().
*/ */

View File

@@ -30,22 +30,6 @@ ssize_t read(
rtems_libio_check_count( count ); rtems_libio_check_count( count );
rtems_libio_check_permissions( iop, LIBIO_FLAGS_READ ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_READ );
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) {
rtems_libio_read_t fp;
fp = rtems_libio_handlers[
(iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].read;
if ( fp == NULL )
set_errno_and_return_minus_one( EBADF );
return (*fp)( fd, buffer, count );
}
/* /*
* Now process the read(). * Now process the read().
*/ */

View File

@@ -38,22 +38,6 @@ ssize_t write(
rtems_libio_check_count( count ); rtems_libio_check_count( count );
rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) {
rtems_libio_write_t fp;
fp = rtems_libio_handlers[
(iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].write;
if ( fp == NULL )
set_errno_and_return_minus_one( EBADF );
return (*fp)( fd, buffer, count );
}
/* /*
* Now process the write() request. * Now process the write() request.
*/ */

View File

@@ -174,8 +174,6 @@ void arpintr (void);
void bootpc_init(void); void bootpc_init(void);
int socket (int, int, int); int socket (int, int, int);
int ioctl (int, unsigned long, ...); int ioctl (int, unsigned long, ...);
struct socket *rtems_bsdnet_fdToSocket (int fd);
int rtems_bsdnet_makeFdForSocket (void *);
/* /*
* Events used by networking routines. * Events used by networking routines.

View File

@@ -78,8 +78,6 @@ struct in_addr rtems_bsdnet_nameserver[sizeof rtems_bsdnet_config.name_server /
sizeof rtems_bsdnet_config.name_server[0]]; sizeof rtems_bsdnet_config.name_server[0]];
int rtems_bsdnet_nameserver_count; int rtems_bsdnet_nameserver_count;
extern rtems_libio_handler_t rtems_bsdnet_io_handler;
/* /*
* Perform FreeBSD memory allocation. * Perform FreeBSD memory allocation.
* FIXME: This should be modified to keep memory allocation statistics. * FIXME: This should be modified to keep memory allocation statistics.
@@ -230,12 +228,6 @@ rtems_bsdnet_initialize (void)
*/ */
networkDaemonTid = rtems_bsdnet_newproc ("ntwk", 4096, networkDaemon, NULL); networkDaemonTid = rtems_bsdnet_newproc ("ntwk", 4096, networkDaemon, NULL);
/*
* Register as an external I/O handler
*/
rtems_register_libio_handler (LIBIO_FLAGS_HANDLER_SOCK,
&rtems_bsdnet_io_handler);
/* /*
* Let other network tasks begin * Let other network tasks begin
*/ */

View File

@@ -46,6 +46,7 @@
*/ */
static __inline int imin(int a, int b) { return (a < b ? a : b); } static __inline int imin(int a, int b) { return (a < b ? a : b); }
struct socket *rtems_bsdnet_fdToSocket(int fd);
static int static int
socket_select (struct socket *so, int which, rtems_id tid) socket_select (struct socket *so, int which, rtems_id tid)

View File

@@ -25,6 +25,13 @@
#include <net/if.h> #include <net/if.h>
#include <net/route.h> #include <net/route.h>
/*
* Hooks to RTEMS I/O system
*/
static const rtems_filesystem_file_handlers_r socket_handlers;
int rtems_bsdnet_makeFdForSocket(void *so, const rtems_filesystem_file_handlers_r *h);
struct socket *rtems_bsdnet_fdToSocket(int fd);
/* /*
* Package system call argument into mbuf. * Package system call argument into mbuf.
*/ */
@@ -64,7 +71,7 @@ socket (int domain, int type, int protocol)
rtems_bsdnet_semaphore_obtain (); rtems_bsdnet_semaphore_obtain ();
error = socreate(domain, &so, type, protocol, NULL); error = socreate(domain, &so, type, protocol, NULL);
if (error == 0) { if (error == 0) {
fd = rtems_bsdnet_makeFdForSocket (so); fd = rtems_bsdnet_makeFdForSocket (so, &socket_handlers);
if (fd < 0) if (fd < 0)
soclose (so); soclose (so);
} }
@@ -213,7 +220,7 @@ accept (int s, struct sockaddr *name, int *namelen)
TAILQ_REMOVE(&head->so_comp, so, so_list); TAILQ_REMOVE(&head->so_comp, so, so_list);
head->so_qlen--; head->so_qlen--;
fd = rtems_bsdnet_makeFdForSocket (so); fd = rtems_bsdnet_makeFdForSocket (so, &socket_handlers);
if (fd < 0) { if (fd < 0) {
TAILQ_INSERT_HEAD(&head->so_comp, so, so_list); TAILQ_INSERT_HEAD(&head->so_comp, so, so_list);
head->so_qlen++; head->so_qlen++;
@@ -600,17 +607,18 @@ getsockname (int s, struct sockaddr *name, int *namelen)
/* /*
************************************************************************ ************************************************************************
* RTEMS EXTERNAL I/O HANDLER ROUTINES * * RTEMS I/O HANDLER ROUTINES *
************************************************************************ ************************************************************************
*/ */
static int static int
rtems_bsdnet_close (int fd) rtems_bsdnet_close (rtems_libio_t *iop)
{ {
struct socket *so; struct socket *so;
int error; int error;
rtems_bsdnet_semaphore_obtain (); rtems_bsdnet_semaphore_obtain ();
if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { if ((so = iop->data1) == NULL) {
errno = EBADF;
rtems_bsdnet_semaphore_release (); rtems_bsdnet_semaphore_release ();
return -1; return -1;
} }
@@ -624,15 +632,15 @@ rtems_bsdnet_close (int fd)
} }
static int static int
rtems_bsdnet_read (int fd, void *buffer, unsigned32 count) rtems_bsdnet_read (rtems_libio_t *iop, void *buffer, unsigned32 count)
{ {
return recv (fd, buffer, count, 0); return recv (iop->data0, buffer, count, 0);
} }
static int static int
rtems_bsdnet_write (int fd, const void *buffer, unsigned32 count) rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, unsigned32 count)
{ {
return send (fd, buffer, count, 0); return send (iop->data0, buffer, count, 0);
} }
static int static int
@@ -659,13 +667,14 @@ so_ioctl (struct socket *so, unsigned32 command, void *buffer)
} }
static int static int
rtems_bsdnet_ioctl (int fd, unsigned32 command, void *buffer) rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
{ {
struct socket *so; struct socket *so;
int error; int error;
rtems_bsdnet_semaphore_obtain (); rtems_bsdnet_semaphore_obtain ();
if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { if ((so = iop->data1) == NULL) {
errno = EBADF;
rtems_bsdnet_semaphore_release (); rtems_bsdnet_semaphore_release ();
return -1; return -1;
} }
@@ -678,12 +687,24 @@ rtems_bsdnet_ioctl (int fd, unsigned32 command, void *buffer)
return 0; return 0;
} }
rtems_libio_handler_t rtems_bsdnet_io_handler = { static int
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
{
sp->st_mode = S_IFSOCK;
return 0;
}
static const rtems_filesystem_file_handlers_r socket_handlers = {
NULL, /* open */ NULL, /* open */
rtems_bsdnet_close, /* close */ rtems_bsdnet_close, /* close */
rtems_bsdnet_read, /* read */ rtems_bsdnet_read, /* read */
rtems_bsdnet_write, /* write */ rtems_bsdnet_write, /* write */
rtems_bsdnet_ioctl, /* ioctl */ rtems_bsdnet_ioctl, /* ioctl */
NULL, /* lseek */ NULL, /* lseek */
rtems_bsdnet_fstat, /* fstat */
NULL, /* fchmod */
NULL, /* ftruncate */
NULL, /* fpathconf */
NULL, /* fsync */
NULL, /* fdatasync */
}; };

View File

@@ -397,15 +397,8 @@ typedef struct {
#define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */ #define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */
#define LIBIO_FLAGS_CREATE 0x0400 /* create file */ #define LIBIO_FLAGS_CREATE 0x0400 /* create file */
#define LIBIO_FLAGS_CLOSE_ON_EXEC 0x0800 /* close on process exec() */ #define LIBIO_FLAGS_CLOSE_ON_EXEC 0x0800 /* close on process exec() */
#define LIBIO_FLAGS_HANDLER_SHIFT 12
#define LIBIO_FLAGS_HANDLER_MASK 0xF000 /* mask for external handler type */
#define LIBIO_FLAGS_HANDLER_RTEMS 0x0000 /* `traditional' RTEMS I/O */
#define LIBIO_FLAGS_HANDLER_SOCK 0x1000 /* BSD socket */
#define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE) #define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE)
void rtems_libio_init(void); void rtems_libio_init(void);
/* /*
@@ -446,35 +439,6 @@ typedef int (*rtems_libio_lseek_t)(
int whence int whence
); );
typedef struct {
rtems_libio_open_t open;
rtems_libio_close_t close;
rtems_libio_read_t read;
rtems_libio_write_t write;
rtems_libio_ioctl_t ioctl;
rtems_libio_lseek_t lseek;
} rtems_libio_handler_t;
/*
* Register a set of external handlers
*/
void rtems_register_libio_handler(
int handler_flag,
const rtems_libio_handler_t *handler
);
/*
* Macros to assist in management of external IO handlers.
*/
#define RTEMS_FILE_DESCRIPTOR_TYPE_FILE 0x0000
#define RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET 0x1000
#define rtems_make_file_descriptor(fd,flags) ((fd)|(flags))
#define rtems_file_descriptor_base(fd) ((fd) & 0x0FFF)
#define rtems_file_descriptor_type(fd) ((fd) & 0xF000)
#define rtems_file_descriptor_type_index(fd) ((((fd) & 0xF000) >> 12) - 1)
/* /*
* IOCTL values * IOCTL values
*/ */

View File

@@ -67,15 +67,6 @@ extern rtems_libio_t *rtems_libio_iops;
extern rtems_libio_t *rtems_libio_last_iop; extern rtems_libio_t *rtems_libio_last_iop;
extern rtems_libio_t *rtems_libio_iop_freelist; extern rtems_libio_t *rtems_libio_iop_freelist;
/*
* External I/O Handlers Table
*
* Space for all possible handlers is preallocated
* to speed up dispatch to external handlers.
*/
extern rtems_libio_handler_t rtems_libio_handlers[15];
/* /*
* Default mode for all files. * Default mode for all files.
*/ */

View File

@@ -20,35 +20,17 @@ int close(
{ {
rtems_libio_t *iop; rtems_libio_t *iop;
rtems_status_code rc; rtems_status_code rc;
int status;
rtems_libio_check_fd(fd); rtems_libio_check_fd(fd);
iop = rtems_libio_iop(fd); iop = rtems_libio_iop(fd);
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) {
int (*fp)(int fd);
fp = rtems_libio_handlers[ rc = RTEMS_SUCCESSFUL;
(iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].close; if ( iop->handlers->close )
if ( fp == NULL ) rc = (*iop->handlers->close)( iop );
set_errno_and_return_minus_one( EBADF );
status = (*fp)( fd );
return status;
}
if ( !iop->handlers )
set_errno_and_return_minus_one( EBADF );
if ( !iop->handlers->close )
set_errno_and_return_minus_one( ENOTSUP );
rc = (*iop->handlers->close)( iop );
rtems_libio_free( iop ); rtems_libio_free( iop );
if (rc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one( rc );
return rc; return rc;
} }

View File

@@ -31,13 +31,6 @@ int fchmod(
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* If this is not a file system based entity, it is an error.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the fchmod(). * Now process the fchmod().
*/ */

View File

@@ -36,13 +36,6 @@ int fcntl(
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* If this is not a file system based entity, it is an error.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the fcntl(). * Now process the fcntl().
*/ */

View File

@@ -27,14 +27,6 @@ int fdatasync(
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the fdatasync(). * Now process the fdatasync().
*/ */

View File

@@ -31,15 +31,6 @@ long fpathconf(
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ); rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ);
/*
* If this file descriptor is mapped to an external set of handlers,
* then it is an error since fpathconf() is not included in the
* set.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the information request. * Now process the information request.
*/ */

View File

@@ -32,34 +32,6 @@ int fstat(
if ( !sbuf ) if ( !sbuf )
set_errno_and_return_minus_one( EFAULT ); set_errno_and_return_minus_one( EFAULT );
/*
* Zero out the stat structure so the various support
* versions of stat don't have to.
*/
memset( sbuf, 0, sizeof(struct stat) );
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if (rtems_file_descriptor_type(fd)) {
switch (rtems_file_descriptor_type (fd)) {
case RTEMS_FILE_DESCRIPTOR_TYPE_FILE:
break;
case RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET:
#if !defined(__GO32__)
sbuf->st_mode = S_IFSOCK;
break;
#endif
default:
set_errno_and_return_minus_one( EBADF );
}
}
/* /*
* Now process the stat() request. * Now process the stat() request.
*/ */
@@ -68,9 +40,18 @@ int fstat(
rtems_libio_check_fd( fd ); rtems_libio_check_fd( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
if ( !iop->handlers )
set_errno_and_return_minus_one( EBADF );
if ( !iop->handlers->fstat ) if ( !iop->handlers->fstat )
set_errno_and_return_minus_one( ENOTSUP ); set_errno_and_return_minus_one( ENOTSUP );
/*
* Zero out the stat structure so the various support
* versions of stat don't have to.
*/
memset( sbuf, 0, sizeof(struct stat) );
return (*iop->handlers->fstat)( &iop->pathinfo, sbuf ); return (*iop->handlers->fstat)( &iop->pathinfo, sbuf );
} }

View File

@@ -27,14 +27,6 @@ int fsync(
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the fsync(). * Now process the fsync().
*/ */

View File

@@ -29,13 +29,6 @@ int ftruncate(
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* If this is not a file system based entity, it is an error.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the ftruncate() request. * Now process the ftruncate() request.
*/ */

View File

@@ -30,22 +30,6 @@ int ioctl(
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) {
rtems_libio_ioctl_t fp;
fp = rtems_libio_handlers[
(iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].ioctl;
if ( fp == NULL )
set_errno_and_return_minus_one( EBADF );
return (*fp)( fd, command, buffer );
}
/* /*
* Now process the ioctl(). * Now process the ioctl().
*/ */

View File

@@ -49,44 +49,12 @@ rtems_libio_t *rtems_libio_iops;
rtems_libio_t *rtems_libio_last_iop; rtems_libio_t *rtems_libio_last_iop;
rtems_libio_t *rtems_libio_iop_freelist; rtems_libio_t *rtems_libio_iop_freelist;
/*
* External I/O Handlers Table
*
* Space for all possible handlers is preallocated
* to speed up dispatch to external handlers.
*/
rtems_libio_handler_t rtems_libio_handlers[15];
/* /*
* Default mode for all files. * Default mode for all files.
*/ */
mode_t rtems_filesystem_umask; mode_t rtems_filesystem_umask;
/*
* rtems_register_libio_handler
*
* This function registers an external IO handler set. This lets
* other subsystems have their own versions of many of the system
* calls. For example, the networking code registers handlers which
* map the system calls for read() and write() to socket calls.
*
*/
void rtems_register_libio_handler(
int handler_flag,
const rtems_libio_handler_t *handler
)
{
int handler_index = (handler_flag >> LIBIO_FLAGS_HANDLER_SHIFT) - 1;
if ((handler_index < 0) || (handler_index >= 15))
rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER );
rtems_libio_handlers[handler_index] = *handler;
}
/* /*
* rtems_libio_init * rtems_libio_init
* *

View File

@@ -397,15 +397,8 @@ typedef struct {
#define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */ #define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */
#define LIBIO_FLAGS_CREATE 0x0400 /* create file */ #define LIBIO_FLAGS_CREATE 0x0400 /* create file */
#define LIBIO_FLAGS_CLOSE_ON_EXEC 0x0800 /* close on process exec() */ #define LIBIO_FLAGS_CLOSE_ON_EXEC 0x0800 /* close on process exec() */
#define LIBIO_FLAGS_HANDLER_SHIFT 12
#define LIBIO_FLAGS_HANDLER_MASK 0xF000 /* mask for external handler type */
#define LIBIO_FLAGS_HANDLER_RTEMS 0x0000 /* `traditional' RTEMS I/O */
#define LIBIO_FLAGS_HANDLER_SOCK 0x1000 /* BSD socket */
#define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE) #define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE)
void rtems_libio_init(void); void rtems_libio_init(void);
/* /*
@@ -446,35 +439,6 @@ typedef int (*rtems_libio_lseek_t)(
int whence int whence
); );
typedef struct {
rtems_libio_open_t open;
rtems_libio_close_t close;
rtems_libio_read_t read;
rtems_libio_write_t write;
rtems_libio_ioctl_t ioctl;
rtems_libio_lseek_t lseek;
} rtems_libio_handler_t;
/*
* Register a set of external handlers
*/
void rtems_register_libio_handler(
int handler_flag,
const rtems_libio_handler_t *handler
);
/*
* Macros to assist in management of external IO handlers.
*/
#define RTEMS_FILE_DESCRIPTOR_TYPE_FILE 0x0000
#define RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET 0x1000
#define rtems_make_file_descriptor(fd,flags) ((fd)|(flags))
#define rtems_file_descriptor_base(fd) ((fd) & 0x0FFF)
#define rtems_file_descriptor_type(fd) ((fd) & 0xF000)
#define rtems_file_descriptor_type_index(fd) ((((fd) & 0xF000) >> 12) - 1)
/* /*
* IOCTL values * IOCTL values
*/ */

View File

@@ -67,15 +67,6 @@ extern rtems_libio_t *rtems_libio_iops;
extern rtems_libio_t *rtems_libio_last_iop; extern rtems_libio_t *rtems_libio_last_iop;
extern rtems_libio_t *rtems_libio_iop_freelist; extern rtems_libio_t *rtems_libio_iop_freelist;
/*
* External I/O Handlers Table
*
* Space for all possible handlers is preallocated
* to speed up dispatch to external handlers.
*/
extern rtems_libio_handler_t rtems_libio_handlers[15];
/* /*
* Default mode for all files. * Default mode for all files.
*/ */

View File

@@ -18,7 +18,6 @@
#include <errno.h> #include <errno.h>
/* /*
* Convert an RTEMS file descriptor to a BSD socket pointer. * Convert an RTEMS file descriptor to a BSD socket pointer.
*/ */
@@ -29,11 +28,13 @@ struct socket *rtems_bsdnet_fdToSocket(
{ {
rtems_libio_t *iop; rtems_libio_t *iop;
if ((unsigned32)fd >= rtems_libio_number_iops) if ((unsigned32)fd >= rtems_libio_number_iops) {
return NULL; errno = EBADF;
return NULL;
}
iop = &rtems_libio_iops[fd]; iop = &rtems_libio_iops[fd];
if ((iop->flags & LIBIO_FLAGS_HANDLER_MASK) != LIBIO_FLAGS_HANDLER_SOCK) if (iop->data1 == NULL)
return NULL; errno = EBADF;
return iop->data1; return iop->data1;
} }
@@ -42,17 +43,22 @@ struct socket *rtems_bsdnet_fdToSocket(
*/ */
int rtems_bsdnet_makeFdForSocket( int rtems_bsdnet_makeFdForSocket(
void *so void *so,
const rtems_filesystem_file_handlers_r *h
) )
{ {
rtems_libio_t *iop; rtems_libio_t *iop;
int fd;
iop = rtems_libio_allocate(); iop = rtems_libio_allocate();
if (iop == 0) { if (iop == 0) {
errno = ENFILE; errno = ENFILE;
return -1; return -1;
} }
iop->flags |= LIBIO_FLAGS_HANDLER_SOCK | LIBIO_FLAGS_WRITE | LIBIO_FLAGS_READ; fd = iop - rtems_libio_iops;
iop->flags |= LIBIO_FLAGS_WRITE | LIBIO_FLAGS_READ;
iop->data0 = fd;
iop->data1 = so; iop->data1 = so;
return iop - rtems_libio_iops; iop->handlers = h;
return fd;
} }

View File

@@ -28,22 +28,6 @@ off_t lseek(
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) {
rtems_libio_lseek_t fp;
fp = rtems_libio_handlers[
(iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].lseek;
if ( fp == NULL )
set_errno_and_return_minus_one( EBADF );
return (*fp)( fd, offset, whence );
}
/* /*
* Now process the lseek(). * Now process the lseek().
*/ */

View File

@@ -30,22 +30,6 @@ ssize_t read(
rtems_libio_check_count( count ); rtems_libio_check_count( count );
rtems_libio_check_permissions( iop, LIBIO_FLAGS_READ ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_READ );
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) {
rtems_libio_read_t fp;
fp = rtems_libio_handlers[
(iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].read;
if ( fp == NULL )
set_errno_and_return_minus_one( EBADF );
return (*fp)( fd, buffer, count );
}
/* /*
* Now process the read(). * Now process the read().
*/ */

View File

@@ -38,22 +38,6 @@ ssize_t write(
rtems_libio_check_count( count ); rtems_libio_check_count( count );
rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) {
rtems_libio_write_t fp;
fp = rtems_libio_handlers[
(iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].write;
if ( fp == NULL )
set_errno_and_return_minus_one( EBADF );
return (*fp)( fd, buffer, count );
}
/* /*
* Now process the write() request. * Now process the write() request.
*/ */

View File

@@ -174,8 +174,6 @@ void arpintr (void);
void bootpc_init(void); void bootpc_init(void);
int socket (int, int, int); int socket (int, int, int);
int ioctl (int, unsigned long, ...); int ioctl (int, unsigned long, ...);
struct socket *rtems_bsdnet_fdToSocket (int fd);
int rtems_bsdnet_makeFdForSocket (void *);
/* /*
* Events used by networking routines. * Events used by networking routines.

View File

@@ -78,8 +78,6 @@ struct in_addr rtems_bsdnet_nameserver[sizeof rtems_bsdnet_config.name_server /
sizeof rtems_bsdnet_config.name_server[0]]; sizeof rtems_bsdnet_config.name_server[0]];
int rtems_bsdnet_nameserver_count; int rtems_bsdnet_nameserver_count;
extern rtems_libio_handler_t rtems_bsdnet_io_handler;
/* /*
* Perform FreeBSD memory allocation. * Perform FreeBSD memory allocation.
* FIXME: This should be modified to keep memory allocation statistics. * FIXME: This should be modified to keep memory allocation statistics.
@@ -230,12 +228,6 @@ rtems_bsdnet_initialize (void)
*/ */
networkDaemonTid = rtems_bsdnet_newproc ("ntwk", 4096, networkDaemon, NULL); networkDaemonTid = rtems_bsdnet_newproc ("ntwk", 4096, networkDaemon, NULL);
/*
* Register as an external I/O handler
*/
rtems_register_libio_handler (LIBIO_FLAGS_HANDLER_SOCK,
&rtems_bsdnet_io_handler);
/* /*
* Let other network tasks begin * Let other network tasks begin
*/ */

View File

@@ -46,6 +46,7 @@
*/ */
static __inline int imin(int a, int b) { return (a < b ? a : b); } static __inline int imin(int a, int b) { return (a < b ? a : b); }
struct socket *rtems_bsdnet_fdToSocket(int fd);
static int static int
socket_select (struct socket *so, int which, rtems_id tid) socket_select (struct socket *so, int which, rtems_id tid)

View File

@@ -25,6 +25,13 @@
#include <net/if.h> #include <net/if.h>
#include <net/route.h> #include <net/route.h>
/*
* Hooks to RTEMS I/O system
*/
static const rtems_filesystem_file_handlers_r socket_handlers;
int rtems_bsdnet_makeFdForSocket(void *so, const rtems_filesystem_file_handlers_r *h);
struct socket *rtems_bsdnet_fdToSocket(int fd);
/* /*
* Package system call argument into mbuf. * Package system call argument into mbuf.
*/ */
@@ -64,7 +71,7 @@ socket (int domain, int type, int protocol)
rtems_bsdnet_semaphore_obtain (); rtems_bsdnet_semaphore_obtain ();
error = socreate(domain, &so, type, protocol, NULL); error = socreate(domain, &so, type, protocol, NULL);
if (error == 0) { if (error == 0) {
fd = rtems_bsdnet_makeFdForSocket (so); fd = rtems_bsdnet_makeFdForSocket (so, &socket_handlers);
if (fd < 0) if (fd < 0)
soclose (so); soclose (so);
} }
@@ -213,7 +220,7 @@ accept (int s, struct sockaddr *name, int *namelen)
TAILQ_REMOVE(&head->so_comp, so, so_list); TAILQ_REMOVE(&head->so_comp, so, so_list);
head->so_qlen--; head->so_qlen--;
fd = rtems_bsdnet_makeFdForSocket (so); fd = rtems_bsdnet_makeFdForSocket (so, &socket_handlers);
if (fd < 0) { if (fd < 0) {
TAILQ_INSERT_HEAD(&head->so_comp, so, so_list); TAILQ_INSERT_HEAD(&head->so_comp, so, so_list);
head->so_qlen++; head->so_qlen++;
@@ -600,17 +607,18 @@ getsockname (int s, struct sockaddr *name, int *namelen)
/* /*
************************************************************************ ************************************************************************
* RTEMS EXTERNAL I/O HANDLER ROUTINES * * RTEMS I/O HANDLER ROUTINES *
************************************************************************ ************************************************************************
*/ */
static int static int
rtems_bsdnet_close (int fd) rtems_bsdnet_close (rtems_libio_t *iop)
{ {
struct socket *so; struct socket *so;
int error; int error;
rtems_bsdnet_semaphore_obtain (); rtems_bsdnet_semaphore_obtain ();
if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { if ((so = iop->data1) == NULL) {
errno = EBADF;
rtems_bsdnet_semaphore_release (); rtems_bsdnet_semaphore_release ();
return -1; return -1;
} }
@@ -624,15 +632,15 @@ rtems_bsdnet_close (int fd)
} }
static int static int
rtems_bsdnet_read (int fd, void *buffer, unsigned32 count) rtems_bsdnet_read (rtems_libio_t *iop, void *buffer, unsigned32 count)
{ {
return recv (fd, buffer, count, 0); return recv (iop->data0, buffer, count, 0);
} }
static int static int
rtems_bsdnet_write (int fd, const void *buffer, unsigned32 count) rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, unsigned32 count)
{ {
return send (fd, buffer, count, 0); return send (iop->data0, buffer, count, 0);
} }
static int static int
@@ -659,13 +667,14 @@ so_ioctl (struct socket *so, unsigned32 command, void *buffer)
} }
static int static int
rtems_bsdnet_ioctl (int fd, unsigned32 command, void *buffer) rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
{ {
struct socket *so; struct socket *so;
int error; int error;
rtems_bsdnet_semaphore_obtain (); rtems_bsdnet_semaphore_obtain ();
if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { if ((so = iop->data1) == NULL) {
errno = EBADF;
rtems_bsdnet_semaphore_release (); rtems_bsdnet_semaphore_release ();
return -1; return -1;
} }
@@ -678,12 +687,24 @@ rtems_bsdnet_ioctl (int fd, unsigned32 command, void *buffer)
return 0; return 0;
} }
rtems_libio_handler_t rtems_bsdnet_io_handler = { static int
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
{
sp->st_mode = S_IFSOCK;
return 0;
}
static const rtems_filesystem_file_handlers_r socket_handlers = {
NULL, /* open */ NULL, /* open */
rtems_bsdnet_close, /* close */ rtems_bsdnet_close, /* close */
rtems_bsdnet_read, /* read */ rtems_bsdnet_read, /* read */
rtems_bsdnet_write, /* write */ rtems_bsdnet_write, /* write */
rtems_bsdnet_ioctl, /* ioctl */ rtems_bsdnet_ioctl, /* ioctl */
NULL, /* lseek */ NULL, /* lseek */
rtems_bsdnet_fstat, /* fstat */
NULL, /* fchmod */
NULL, /* ftruncate */
NULL, /* fpathconf */
NULL, /* fsync */
NULL, /* fdatasync */
}; };

View File

@@ -174,8 +174,6 @@ void arpintr (void);
void bootpc_init(void); void bootpc_init(void);
int socket (int, int, int); int socket (int, int, int);
int ioctl (int, unsigned long, ...); int ioctl (int, unsigned long, ...);
struct socket *rtems_bsdnet_fdToSocket (int fd);
int rtems_bsdnet_makeFdForSocket (void *);
/* /*
* Events used by networking routines. * Events used by networking routines.

View File

@@ -78,8 +78,6 @@ struct in_addr rtems_bsdnet_nameserver[sizeof rtems_bsdnet_config.name_server /
sizeof rtems_bsdnet_config.name_server[0]]; sizeof rtems_bsdnet_config.name_server[0]];
int rtems_bsdnet_nameserver_count; int rtems_bsdnet_nameserver_count;
extern rtems_libio_handler_t rtems_bsdnet_io_handler;
/* /*
* Perform FreeBSD memory allocation. * Perform FreeBSD memory allocation.
* FIXME: This should be modified to keep memory allocation statistics. * FIXME: This should be modified to keep memory allocation statistics.
@@ -230,12 +228,6 @@ rtems_bsdnet_initialize (void)
*/ */
networkDaemonTid = rtems_bsdnet_newproc ("ntwk", 4096, networkDaemon, NULL); networkDaemonTid = rtems_bsdnet_newproc ("ntwk", 4096, networkDaemon, NULL);
/*
* Register as an external I/O handler
*/
rtems_register_libio_handler (LIBIO_FLAGS_HANDLER_SOCK,
&rtems_bsdnet_io_handler);
/* /*
* Let other network tasks begin * Let other network tasks begin
*/ */

View File

@@ -46,6 +46,7 @@
*/ */
static __inline int imin(int a, int b) { return (a < b ? a : b); } static __inline int imin(int a, int b) { return (a < b ? a : b); }
struct socket *rtems_bsdnet_fdToSocket(int fd);
static int static int
socket_select (struct socket *so, int which, rtems_id tid) socket_select (struct socket *so, int which, rtems_id tid)

View File

@@ -25,6 +25,13 @@
#include <net/if.h> #include <net/if.h>
#include <net/route.h> #include <net/route.h>
/*
* Hooks to RTEMS I/O system
*/
static const rtems_filesystem_file_handlers_r socket_handlers;
int rtems_bsdnet_makeFdForSocket(void *so, const rtems_filesystem_file_handlers_r *h);
struct socket *rtems_bsdnet_fdToSocket(int fd);
/* /*
* Package system call argument into mbuf. * Package system call argument into mbuf.
*/ */
@@ -64,7 +71,7 @@ socket (int domain, int type, int protocol)
rtems_bsdnet_semaphore_obtain (); rtems_bsdnet_semaphore_obtain ();
error = socreate(domain, &so, type, protocol, NULL); error = socreate(domain, &so, type, protocol, NULL);
if (error == 0) { if (error == 0) {
fd = rtems_bsdnet_makeFdForSocket (so); fd = rtems_bsdnet_makeFdForSocket (so, &socket_handlers);
if (fd < 0) if (fd < 0)
soclose (so); soclose (so);
} }
@@ -213,7 +220,7 @@ accept (int s, struct sockaddr *name, int *namelen)
TAILQ_REMOVE(&head->so_comp, so, so_list); TAILQ_REMOVE(&head->so_comp, so, so_list);
head->so_qlen--; head->so_qlen--;
fd = rtems_bsdnet_makeFdForSocket (so); fd = rtems_bsdnet_makeFdForSocket (so, &socket_handlers);
if (fd < 0) { if (fd < 0) {
TAILQ_INSERT_HEAD(&head->so_comp, so, so_list); TAILQ_INSERT_HEAD(&head->so_comp, so, so_list);
head->so_qlen++; head->so_qlen++;
@@ -600,17 +607,18 @@ getsockname (int s, struct sockaddr *name, int *namelen)
/* /*
************************************************************************ ************************************************************************
* RTEMS EXTERNAL I/O HANDLER ROUTINES * * RTEMS I/O HANDLER ROUTINES *
************************************************************************ ************************************************************************
*/ */
static int static int
rtems_bsdnet_close (int fd) rtems_bsdnet_close (rtems_libio_t *iop)
{ {
struct socket *so; struct socket *so;
int error; int error;
rtems_bsdnet_semaphore_obtain (); rtems_bsdnet_semaphore_obtain ();
if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { if ((so = iop->data1) == NULL) {
errno = EBADF;
rtems_bsdnet_semaphore_release (); rtems_bsdnet_semaphore_release ();
return -1; return -1;
} }
@@ -624,15 +632,15 @@ rtems_bsdnet_close (int fd)
} }
static int static int
rtems_bsdnet_read (int fd, void *buffer, unsigned32 count) rtems_bsdnet_read (rtems_libio_t *iop, void *buffer, unsigned32 count)
{ {
return recv (fd, buffer, count, 0); return recv (iop->data0, buffer, count, 0);
} }
static int static int
rtems_bsdnet_write (int fd, const void *buffer, unsigned32 count) rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, unsigned32 count)
{ {
return send (fd, buffer, count, 0); return send (iop->data0, buffer, count, 0);
} }
static int static int
@@ -659,13 +667,14 @@ so_ioctl (struct socket *so, unsigned32 command, void *buffer)
} }
static int static int
rtems_bsdnet_ioctl (int fd, unsigned32 command, void *buffer) rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
{ {
struct socket *so; struct socket *so;
int error; int error;
rtems_bsdnet_semaphore_obtain (); rtems_bsdnet_semaphore_obtain ();
if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { if ((so = iop->data1) == NULL) {
errno = EBADF;
rtems_bsdnet_semaphore_release (); rtems_bsdnet_semaphore_release ();
return -1; return -1;
} }
@@ -678,12 +687,24 @@ rtems_bsdnet_ioctl (int fd, unsigned32 command, void *buffer)
return 0; return 0;
} }
rtems_libio_handler_t rtems_bsdnet_io_handler = { static int
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
{
sp->st_mode = S_IFSOCK;
return 0;
}
static const rtems_filesystem_file_handlers_r socket_handlers = {
NULL, /* open */ NULL, /* open */
rtems_bsdnet_close, /* close */ rtems_bsdnet_close, /* close */
rtems_bsdnet_read, /* read */ rtems_bsdnet_read, /* read */
rtems_bsdnet_write, /* write */ rtems_bsdnet_write, /* write */
rtems_bsdnet_ioctl, /* ioctl */ rtems_bsdnet_ioctl, /* ioctl */
NULL, /* lseek */ NULL, /* lseek */
rtems_bsdnet_fstat, /* fstat */
NULL, /* fchmod */
NULL, /* ftruncate */
NULL, /* fpathconf */
NULL, /* fsync */
NULL, /* fdatasync */
}; };

View File

@@ -67,15 +67,6 @@ extern rtems_libio_t *rtems_libio_iops;
extern rtems_libio_t *rtems_libio_last_iop; extern rtems_libio_t *rtems_libio_last_iop;
extern rtems_libio_t *rtems_libio_iop_freelist; extern rtems_libio_t *rtems_libio_iop_freelist;
/*
* External I/O Handlers Table
*
* Space for all possible handlers is preallocated
* to speed up dispatch to external handlers.
*/
extern rtems_libio_handler_t rtems_libio_handlers[15];
/* /*
* Default mode for all files. * Default mode for all files.
*/ */

View File

@@ -397,15 +397,8 @@ typedef struct {
#define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */ #define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */
#define LIBIO_FLAGS_CREATE 0x0400 /* create file */ #define LIBIO_FLAGS_CREATE 0x0400 /* create file */
#define LIBIO_FLAGS_CLOSE_ON_EXEC 0x0800 /* close on process exec() */ #define LIBIO_FLAGS_CLOSE_ON_EXEC 0x0800 /* close on process exec() */
#define LIBIO_FLAGS_HANDLER_SHIFT 12
#define LIBIO_FLAGS_HANDLER_MASK 0xF000 /* mask for external handler type */
#define LIBIO_FLAGS_HANDLER_RTEMS 0x0000 /* `traditional' RTEMS I/O */
#define LIBIO_FLAGS_HANDLER_SOCK 0x1000 /* BSD socket */
#define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE) #define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE)
void rtems_libio_init(void); void rtems_libio_init(void);
/* /*
@@ -446,35 +439,6 @@ typedef int (*rtems_libio_lseek_t)(
int whence int whence
); );
typedef struct {
rtems_libio_open_t open;
rtems_libio_close_t close;
rtems_libio_read_t read;
rtems_libio_write_t write;
rtems_libio_ioctl_t ioctl;
rtems_libio_lseek_t lseek;
} rtems_libio_handler_t;
/*
* Register a set of external handlers
*/
void rtems_register_libio_handler(
int handler_flag,
const rtems_libio_handler_t *handler
);
/*
* Macros to assist in management of external IO handlers.
*/
#define RTEMS_FILE_DESCRIPTOR_TYPE_FILE 0x0000
#define RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET 0x1000
#define rtems_make_file_descriptor(fd,flags) ((fd)|(flags))
#define rtems_file_descriptor_base(fd) ((fd) & 0x0FFF)
#define rtems_file_descriptor_type(fd) ((fd) & 0xF000)
#define rtems_file_descriptor_type_index(fd) ((((fd) & 0xF000) >> 12) - 1)
/* /*
* IOCTL values * IOCTL values
*/ */

View File

@@ -67,15 +67,6 @@ extern rtems_libio_t *rtems_libio_iops;
extern rtems_libio_t *rtems_libio_last_iop; extern rtems_libio_t *rtems_libio_last_iop;
extern rtems_libio_t *rtems_libio_iop_freelist; extern rtems_libio_t *rtems_libio_iop_freelist;
/*
* External I/O Handlers Table
*
* Space for all possible handlers is preallocated
* to speed up dispatch to external handlers.
*/
extern rtems_libio_handler_t rtems_libio_handlers[15];
/* /*
* Default mode for all files. * Default mode for all files.
*/ */

View File

@@ -20,35 +20,17 @@ int close(
{ {
rtems_libio_t *iop; rtems_libio_t *iop;
rtems_status_code rc; rtems_status_code rc;
int status;
rtems_libio_check_fd(fd); rtems_libio_check_fd(fd);
iop = rtems_libio_iop(fd); iop = rtems_libio_iop(fd);
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) {
int (*fp)(int fd);
fp = rtems_libio_handlers[ rc = RTEMS_SUCCESSFUL;
(iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].close; if ( iop->handlers->close )
if ( fp == NULL ) rc = (*iop->handlers->close)( iop );
set_errno_and_return_minus_one( EBADF );
status = (*fp)( fd );
return status;
}
if ( !iop->handlers )
set_errno_and_return_minus_one( EBADF );
if ( !iop->handlers->close )
set_errno_and_return_minus_one( ENOTSUP );
rc = (*iop->handlers->close)( iop );
rtems_libio_free( iop ); rtems_libio_free( iop );
if (rc != RTEMS_SUCCESSFUL)
set_errno_and_return_minus_one( rc );
return rc; return rc;
} }

View File

@@ -31,13 +31,6 @@ int fchmod(
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* If this is not a file system based entity, it is an error.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the fchmod(). * Now process the fchmod().
*/ */

View File

@@ -36,13 +36,6 @@ int fcntl(
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* If this is not a file system based entity, it is an error.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the fcntl(). * Now process the fcntl().
*/ */

View File

@@ -27,14 +27,6 @@ int fdatasync(
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the fdatasync(). * Now process the fdatasync().
*/ */

View File

@@ -31,15 +31,6 @@ long fpathconf(
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ); rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ);
/*
* If this file descriptor is mapped to an external set of handlers,
* then it is an error since fpathconf() is not included in the
* set.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the information request. * Now process the information request.
*/ */

View File

@@ -32,34 +32,6 @@ int fstat(
if ( !sbuf ) if ( !sbuf )
set_errno_and_return_minus_one( EFAULT ); set_errno_and_return_minus_one( EFAULT );
/*
* Zero out the stat structure so the various support
* versions of stat don't have to.
*/
memset( sbuf, 0, sizeof(struct stat) );
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if (rtems_file_descriptor_type(fd)) {
switch (rtems_file_descriptor_type (fd)) {
case RTEMS_FILE_DESCRIPTOR_TYPE_FILE:
break;
case RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET:
#if !defined(__GO32__)
sbuf->st_mode = S_IFSOCK;
break;
#endif
default:
set_errno_and_return_minus_one( EBADF );
}
}
/* /*
* Now process the stat() request. * Now process the stat() request.
*/ */
@@ -68,9 +40,18 @@ int fstat(
rtems_libio_check_fd( fd ); rtems_libio_check_fd( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
if ( !iop->handlers )
set_errno_and_return_minus_one( EBADF );
if ( !iop->handlers->fstat ) if ( !iop->handlers->fstat )
set_errno_and_return_minus_one( ENOTSUP ); set_errno_and_return_minus_one( ENOTSUP );
/*
* Zero out the stat structure so the various support
* versions of stat don't have to.
*/
memset( sbuf, 0, sizeof(struct stat) );
return (*iop->handlers->fstat)( &iop->pathinfo, sbuf ); return (*iop->handlers->fstat)( &iop->pathinfo, sbuf );
} }

View File

@@ -27,14 +27,6 @@ int fsync(
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the fsync(). * Now process the fsync().
*/ */

View File

@@ -29,13 +29,6 @@ int ftruncate(
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* If this is not a file system based entity, it is an error.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK )
set_errno_and_return_minus_one( EBADF );
/* /*
* Now process the ftruncate() request. * Now process the ftruncate() request.
*/ */

View File

@@ -30,22 +30,6 @@ int ioctl(
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) {
rtems_libio_ioctl_t fp;
fp = rtems_libio_handlers[
(iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].ioctl;
if ( fp == NULL )
set_errno_and_return_minus_one( EBADF );
return (*fp)( fd, command, buffer );
}
/* /*
* Now process the ioctl(). * Now process the ioctl().
*/ */

View File

@@ -49,44 +49,12 @@ rtems_libio_t *rtems_libio_iops;
rtems_libio_t *rtems_libio_last_iop; rtems_libio_t *rtems_libio_last_iop;
rtems_libio_t *rtems_libio_iop_freelist; rtems_libio_t *rtems_libio_iop_freelist;
/*
* External I/O Handlers Table
*
* Space for all possible handlers is preallocated
* to speed up dispatch to external handlers.
*/
rtems_libio_handler_t rtems_libio_handlers[15];
/* /*
* Default mode for all files. * Default mode for all files.
*/ */
mode_t rtems_filesystem_umask; mode_t rtems_filesystem_umask;
/*
* rtems_register_libio_handler
*
* This function registers an external IO handler set. This lets
* other subsystems have their own versions of many of the system
* calls. For example, the networking code registers handlers which
* map the system calls for read() and write() to socket calls.
*
*/
void rtems_register_libio_handler(
int handler_flag,
const rtems_libio_handler_t *handler
)
{
int handler_index = (handler_flag >> LIBIO_FLAGS_HANDLER_SHIFT) - 1;
if ((handler_index < 0) || (handler_index >= 15))
rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER );
rtems_libio_handlers[handler_index] = *handler;
}
/* /*
* rtems_libio_init * rtems_libio_init
* *

View File

@@ -18,7 +18,6 @@
#include <errno.h> #include <errno.h>
/* /*
* Convert an RTEMS file descriptor to a BSD socket pointer. * Convert an RTEMS file descriptor to a BSD socket pointer.
*/ */
@@ -29,11 +28,13 @@ struct socket *rtems_bsdnet_fdToSocket(
{ {
rtems_libio_t *iop; rtems_libio_t *iop;
if ((unsigned32)fd >= rtems_libio_number_iops) if ((unsigned32)fd >= rtems_libio_number_iops) {
return NULL; errno = EBADF;
return NULL;
}
iop = &rtems_libio_iops[fd]; iop = &rtems_libio_iops[fd];
if ((iop->flags & LIBIO_FLAGS_HANDLER_MASK) != LIBIO_FLAGS_HANDLER_SOCK) if (iop->data1 == NULL)
return NULL; errno = EBADF;
return iop->data1; return iop->data1;
} }
@@ -42,17 +43,22 @@ struct socket *rtems_bsdnet_fdToSocket(
*/ */
int rtems_bsdnet_makeFdForSocket( int rtems_bsdnet_makeFdForSocket(
void *so void *so,
const rtems_filesystem_file_handlers_r *h
) )
{ {
rtems_libio_t *iop; rtems_libio_t *iop;
int fd;
iop = rtems_libio_allocate(); iop = rtems_libio_allocate();
if (iop == 0) { if (iop == 0) {
errno = ENFILE; errno = ENFILE;
return -1; return -1;
} }
iop->flags |= LIBIO_FLAGS_HANDLER_SOCK | LIBIO_FLAGS_WRITE | LIBIO_FLAGS_READ; fd = iop - rtems_libio_iops;
iop->flags |= LIBIO_FLAGS_WRITE | LIBIO_FLAGS_READ;
iop->data0 = fd;
iop->data1 = so; iop->data1 = so;
return iop - rtems_libio_iops; iop->handlers = h;
return fd;
} }

View File

@@ -28,22 +28,6 @@ off_t lseek(
iop = rtems_libio_iop( fd ); iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop); rtems_libio_check_is_open(iop);
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) {
rtems_libio_lseek_t fp;
fp = rtems_libio_handlers[
(iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].lseek;
if ( fp == NULL )
set_errno_and_return_minus_one( EBADF );
return (*fp)( fd, offset, whence );
}
/* /*
* Now process the lseek(). * Now process the lseek().
*/ */

View File

@@ -30,22 +30,6 @@ ssize_t read(
rtems_libio_check_count( count ); rtems_libio_check_count( count );
rtems_libio_check_permissions( iop, LIBIO_FLAGS_READ ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_READ );
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) {
rtems_libio_read_t fp;
fp = rtems_libio_handlers[
(iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].read;
if ( fp == NULL )
set_errno_and_return_minus_one( EBADF );
return (*fp)( fd, buffer, count );
}
/* /*
* Now process the read(). * Now process the read().
*/ */

View File

@@ -38,22 +38,6 @@ ssize_t write(
rtems_libio_check_count( count ); rtems_libio_check_count( count );
rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE );
/*
* If this file descriptor is mapped to an external set of handlers,
* then pass the request on to them.
*/
if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) {
rtems_libio_write_t fp;
fp = rtems_libio_handlers[
(iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].write;
if ( fp == NULL )
set_errno_and_return_minus_one( EBADF );
return (*fp)( fd, buffer, count );
}
/* /*
* Now process the write() request. * Now process the write() request.
*/ */

View File

@@ -174,8 +174,6 @@ void arpintr (void);
void bootpc_init(void); void bootpc_init(void);
int socket (int, int, int); int socket (int, int, int);
int ioctl (int, unsigned long, ...); int ioctl (int, unsigned long, ...);
struct socket *rtems_bsdnet_fdToSocket (int fd);
int rtems_bsdnet_makeFdForSocket (void *);
/* /*
* Events used by networking routines. * Events used by networking routines.

View File

@@ -78,8 +78,6 @@ struct in_addr rtems_bsdnet_nameserver[sizeof rtems_bsdnet_config.name_server /
sizeof rtems_bsdnet_config.name_server[0]]; sizeof rtems_bsdnet_config.name_server[0]];
int rtems_bsdnet_nameserver_count; int rtems_bsdnet_nameserver_count;
extern rtems_libio_handler_t rtems_bsdnet_io_handler;
/* /*
* Perform FreeBSD memory allocation. * Perform FreeBSD memory allocation.
* FIXME: This should be modified to keep memory allocation statistics. * FIXME: This should be modified to keep memory allocation statistics.
@@ -230,12 +228,6 @@ rtems_bsdnet_initialize (void)
*/ */
networkDaemonTid = rtems_bsdnet_newproc ("ntwk", 4096, networkDaemon, NULL); networkDaemonTid = rtems_bsdnet_newproc ("ntwk", 4096, networkDaemon, NULL);
/*
* Register as an external I/O handler
*/
rtems_register_libio_handler (LIBIO_FLAGS_HANDLER_SOCK,
&rtems_bsdnet_io_handler);
/* /*
* Let other network tasks begin * Let other network tasks begin
*/ */

View File

@@ -46,6 +46,7 @@
*/ */
static __inline int imin(int a, int b) { return (a < b ? a : b); } static __inline int imin(int a, int b) { return (a < b ? a : b); }
struct socket *rtems_bsdnet_fdToSocket(int fd);
static int static int
socket_select (struct socket *so, int which, rtems_id tid) socket_select (struct socket *so, int which, rtems_id tid)

View File

@@ -25,6 +25,13 @@
#include <net/if.h> #include <net/if.h>
#include <net/route.h> #include <net/route.h>
/*
* Hooks to RTEMS I/O system
*/
static const rtems_filesystem_file_handlers_r socket_handlers;
int rtems_bsdnet_makeFdForSocket(void *so, const rtems_filesystem_file_handlers_r *h);
struct socket *rtems_bsdnet_fdToSocket(int fd);
/* /*
* Package system call argument into mbuf. * Package system call argument into mbuf.
*/ */
@@ -64,7 +71,7 @@ socket (int domain, int type, int protocol)
rtems_bsdnet_semaphore_obtain (); rtems_bsdnet_semaphore_obtain ();
error = socreate(domain, &so, type, protocol, NULL); error = socreate(domain, &so, type, protocol, NULL);
if (error == 0) { if (error == 0) {
fd = rtems_bsdnet_makeFdForSocket (so); fd = rtems_bsdnet_makeFdForSocket (so, &socket_handlers);
if (fd < 0) if (fd < 0)
soclose (so); soclose (so);
} }
@@ -213,7 +220,7 @@ accept (int s, struct sockaddr *name, int *namelen)
TAILQ_REMOVE(&head->so_comp, so, so_list); TAILQ_REMOVE(&head->so_comp, so, so_list);
head->so_qlen--; head->so_qlen--;
fd = rtems_bsdnet_makeFdForSocket (so); fd = rtems_bsdnet_makeFdForSocket (so, &socket_handlers);
if (fd < 0) { if (fd < 0) {
TAILQ_INSERT_HEAD(&head->so_comp, so, so_list); TAILQ_INSERT_HEAD(&head->so_comp, so, so_list);
head->so_qlen++; head->so_qlen++;
@@ -600,17 +607,18 @@ getsockname (int s, struct sockaddr *name, int *namelen)
/* /*
************************************************************************ ************************************************************************
* RTEMS EXTERNAL I/O HANDLER ROUTINES * * RTEMS I/O HANDLER ROUTINES *
************************************************************************ ************************************************************************
*/ */
static int static int
rtems_bsdnet_close (int fd) rtems_bsdnet_close (rtems_libio_t *iop)
{ {
struct socket *so; struct socket *so;
int error; int error;
rtems_bsdnet_semaphore_obtain (); rtems_bsdnet_semaphore_obtain ();
if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { if ((so = iop->data1) == NULL) {
errno = EBADF;
rtems_bsdnet_semaphore_release (); rtems_bsdnet_semaphore_release ();
return -1; return -1;
} }
@@ -624,15 +632,15 @@ rtems_bsdnet_close (int fd)
} }
static int static int
rtems_bsdnet_read (int fd, void *buffer, unsigned32 count) rtems_bsdnet_read (rtems_libio_t *iop, void *buffer, unsigned32 count)
{ {
return recv (fd, buffer, count, 0); return recv (iop->data0, buffer, count, 0);
} }
static int static int
rtems_bsdnet_write (int fd, const void *buffer, unsigned32 count) rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, unsigned32 count)
{ {
return send (fd, buffer, count, 0); return send (iop->data0, buffer, count, 0);
} }
static int static int
@@ -659,13 +667,14 @@ so_ioctl (struct socket *so, unsigned32 command, void *buffer)
} }
static int static int
rtems_bsdnet_ioctl (int fd, unsigned32 command, void *buffer) rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
{ {
struct socket *so; struct socket *so;
int error; int error;
rtems_bsdnet_semaphore_obtain (); rtems_bsdnet_semaphore_obtain ();
if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { if ((so = iop->data1) == NULL) {
errno = EBADF;
rtems_bsdnet_semaphore_release (); rtems_bsdnet_semaphore_release ();
return -1; return -1;
} }
@@ -678,12 +687,24 @@ rtems_bsdnet_ioctl (int fd, unsigned32 command, void *buffer)
return 0; return 0;
} }
rtems_libio_handler_t rtems_bsdnet_io_handler = { static int
rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
{
sp->st_mode = S_IFSOCK;
return 0;
}
static const rtems_filesystem_file_handlers_r socket_handlers = {
NULL, /* open */ NULL, /* open */
rtems_bsdnet_close, /* close */ rtems_bsdnet_close, /* close */
rtems_bsdnet_read, /* read */ rtems_bsdnet_read, /* read */
rtems_bsdnet_write, /* write */ rtems_bsdnet_write, /* write */
rtems_bsdnet_ioctl, /* ioctl */ rtems_bsdnet_ioctl, /* ioctl */
NULL, /* lseek */ NULL, /* lseek */
rtems_bsdnet_fstat, /* fstat */
NULL, /* fchmod */
NULL, /* ftruncate */
NULL, /* fpathconf */
NULL, /* fsync */
NULL, /* fdatasync */
}; };