From cca44008d81209e9fa992157637d9de0384e0536 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 10 Dec 1998 23:31:54 +0000 Subject: Merged Eric Norum's select patch that was based on 4.0 and resolved all conflicts. --- VERSION | 2 +- c/src/exec/include/rtems/libio_.h | 1 + c/src/exec/libcsupport/include/rtems/libio.h | 6 +- c/src/exec/libcsupport/include/rtems/libio_.h | 1 + c/src/exec/libcsupport/include/sys/sockio.h | 5 +- c/src/exec/libcsupport/src/close.c | 9 +- c/src/exec/libcsupport/src/fchmod.c | 7 +- c/src/exec/libcsupport/src/fcntl.c | 8 +- c/src/exec/libcsupport/src/fdatasync.c | 10 +- c/src/exec/libcsupport/src/fpathconf.c | 10 +- c/src/exec/libcsupport/src/fsync.c | 10 +- c/src/exec/libcsupport/src/ftruncate.c | 8 +- c/src/exec/libcsupport/src/ioctl.c | 11 +- c/src/exec/libcsupport/src/libio.c | 157 +++++++++++++++---------- c/src/exec/libcsupport/src/lseek.c | 11 +- c/src/exec/libcsupport/src/read.c | 17 +-- c/src/exec/libcsupport/src/write.c | 17 +-- c/src/exec/libnetworking/rtems/rtems_glue.c | 36 +----- c/src/exec/libnetworking/rtems/rtems_syscall.c | 103 +++------------- c/src/lib/include/rtems/libio.h | 6 +- c/src/lib/include/rtems/libio_.h | 1 + c/src/lib/include/sys/sockio.h | 5 +- c/src/lib/libc/close.c | 9 +- c/src/lib/libc/fchmod.c | 7 +- c/src/lib/libc/fcntl.c | 8 +- c/src/lib/libc/fdatasync.c | 10 +- c/src/lib/libc/fpathconf.c | 10 +- c/src/lib/libc/fsync.c | 10 +- c/src/lib/libc/ftruncate.c | 8 +- c/src/lib/libc/ioctl.c | 11 +- c/src/lib/libc/libio.c | 157 +++++++++++++++---------- c/src/lib/libc/libio.h | 6 +- c/src/lib/libc/libio_.h | 1 + c/src/lib/libc/lseek.c | 11 +- c/src/lib/libc/read.c | 17 +-- c/src/lib/libc/write.c | 17 +-- c/src/lib/libnetworking/rtems/Makefile.in | 2 +- c/src/lib/libnetworking/rtems/rtems_glue.c | 36 +----- c/src/lib/libnetworking/rtems/rtems_syscall.c | 103 +++------------- c/src/lib/libnetworking/sys/sockio.h | 5 +- c/src/libnetworking/rtems/Makefile.in | 2 +- c/src/libnetworking/rtems/rtems_glue.c | 36 +----- c/src/libnetworking/rtems/rtems_syscall.c | 103 +++------------- c/src/libnetworking/sys/sockio.h | 5 +- configure | 2 +- configure.in | 2 +- cpukit/include/rtems/libio_.h | 1 + cpukit/libcsupport/include/rtems/libio.h | 6 +- cpukit/libcsupport/include/rtems/libio_.h | 1 + cpukit/libcsupport/include/sys/sockio.h | 5 +- cpukit/libcsupport/src/close.c | 9 +- cpukit/libcsupport/src/fchmod.c | 7 +- cpukit/libcsupport/src/fcntl.c | 8 +- cpukit/libcsupport/src/fdatasync.c | 10 +- cpukit/libcsupport/src/fpathconf.c | 10 +- cpukit/libcsupport/src/fsync.c | 10 +- cpukit/libcsupport/src/ftruncate.c | 8 +- cpukit/libcsupport/src/ioctl.c | 11 +- cpukit/libcsupport/src/libio.c | 157 +++++++++++++++---------- cpukit/libcsupport/src/lseek.c | 11 +- cpukit/libcsupport/src/read.c | 17 +-- cpukit/libcsupport/src/write.c | 17 +-- cpukit/libnetworking/rtems/rtems_glue.c | 36 +----- cpukit/libnetworking/rtems/rtems_syscall.c | 103 +++------------- 64 files changed, 595 insertions(+), 851 deletions(-) diff --git a/VERSION b/VERSION index 3e04abb9d1..6fb76ae59f 100644 --- a/VERSION +++ b/VERSION @@ -2,4 +2,4 @@ # $Id$ # -RTEMS Version 19981203 +RTEMS Version 4.0.0 diff --git a/c/src/exec/include/rtems/libio_.h b/c/src/exec/include/rtems/libio_.h index 33a9e7bda5..d595500430 100644 --- a/c/src/exec/include/rtems/libio_.h +++ b/c/src/exec/include/rtems/libio_.h @@ -65,6 +65,7 @@ extern rtems_id rtems_libio_semaphore; extern unsigned32 rtems_libio_number_iops; extern rtems_libio_t *rtems_libio_iops; extern rtems_libio_t *rtems_libio_last_iop; +extern rtems_libio_t *rtems_libio_iop_freelist; /* * External I/O Handlers Table diff --git a/c/src/exec/libcsupport/include/rtems/libio.h b/c/src/exec/libcsupport/include/rtems/libio.h index ee0aaf9b7f..740574f303 100644 --- a/c/src/exec/libcsupport/include/rtems/libio.h +++ b/c/src/exec/libcsupport/include/rtems/libio.h @@ -393,12 +393,16 @@ typedef struct { #define LIBIO_FLAGS_NO_DELAY 0x0001 /* return immediately if no data */ #define LIBIO_FLAGS_READ 0x0002 /* reading */ #define LIBIO_FLAGS_WRITE 0x0004 /* writing */ -#define LIBIO_FLAGS_LINE_BUFFERED 0x0008 /* line buffered io (^h, ^u, etc) */ #define LIBIO_FLAGS_OPEN 0x0100 /* device is open */ #define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */ #define LIBIO_FLAGS_CREATE 0x0400 /* create file */ #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) diff --git a/c/src/exec/libcsupport/include/rtems/libio_.h b/c/src/exec/libcsupport/include/rtems/libio_.h index 33a9e7bda5..d595500430 100644 --- a/c/src/exec/libcsupport/include/rtems/libio_.h +++ b/c/src/exec/libcsupport/include/rtems/libio_.h @@ -65,6 +65,7 @@ extern rtems_id rtems_libio_semaphore; extern unsigned32 rtems_libio_number_iops; extern rtems_libio_t *rtems_libio_iops; extern rtems_libio_t *rtems_libio_last_iop; +extern rtems_libio_t *rtems_libio_iop_freelist; /* * External I/O Handlers Table diff --git a/c/src/exec/libcsupport/include/sys/sockio.h b/c/src/exec/libcsupport/include/sys/sockio.h index 03ec16e43a..5e54baffe8 100644 --- a/c/src/exec/libcsupport/include/sys/sockio.h +++ b/c/src/exec/libcsupport/include/sys/sockio.h @@ -83,11 +83,10 @@ #define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) /* set net media */ #define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */ - /* * RTEMS additions for setting/getting `tap' function on incoming packets. */ -#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */ -#define SIOCGIFTAP _IOWR('i', 81, struct ifreq) /* get tap function */ +#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */ +#define SIOCGIFTAP _IOW('i', 81, struct ifreq) /* get tap function */ #endif /* !_SYS_SOCKIO_H_ */ diff --git a/c/src/exec/libcsupport/src/close.c b/c/src/exec/libcsupport/src/close.c index 94ddb45c90..0583a36b22 100644 --- a/c/src/exec/libcsupport/src/close.c +++ b/c/src/exec/libcsupport/src/close.c @@ -22,17 +22,18 @@ int close( rtems_status_code rc; int status; - if ( rtems_file_descriptor_type( fd ) ) { + rtems_libio_check_fd(fd); + iop = rtems_libio_iop(fd); + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) { int (*fp)(int fd); - fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].close; + fp = rtems_libio_handlers[ + (iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].close; if ( fp == NULL ) set_errno_and_return_minus_one( EBADF ); status = (*fp)( fd ); return status; } - iop = rtems_libio_iop(fd); - rtems_libio_check_fd(fd); if ( !iop->handlers ) set_errno_and_return_minus_one( EBADF ); diff --git a/c/src/exec/libcsupport/src/fchmod.c b/c/src/exec/libcsupport/src/fchmod.c index a3ca4507ab..f202a30eb0 100644 --- a/c/src/exec/libcsupport/src/fchmod.c +++ b/c/src/exec/libcsupport/src/fchmod.c @@ -27,19 +27,20 @@ int fchmod( { rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + /* * If this is not a file system based entity, it is an error. */ - if ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the fchmod(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); if ( !iop->handlers->fchmod ) diff --git a/c/src/exec/libcsupport/src/fcntl.c b/c/src/exec/libcsupport/src/fcntl.c index a538ec1cf9..b327a447ac 100644 --- a/c/src/exec/libcsupport/src/fcntl.c +++ b/c/src/exec/libcsupport/src/fcntl.c @@ -32,20 +32,20 @@ int fcntl( va_start( ap, cmd ); + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + /* * If this is not a file system based entity, it is an error. */ - if ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the fcntl(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - /* * This switch should contain all the cases from POSIX. */ diff --git a/c/src/exec/libcsupport/src/fdatasync.c b/c/src/exec/libcsupport/src/fdatasync.c index 58a4c4e118..91bff3aaba 100644 --- a/c/src/exec/libcsupport/src/fdatasync.c +++ b/c/src/exec/libcsupport/src/fdatasync.c @@ -22,22 +22,22 @@ int fdatasync( { rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + 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 ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the fdatasync(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); - if ( !iop->handlers->fdatasync ) set_errno_and_return_minus_one( ENOTSUP ); diff --git a/c/src/exec/libcsupport/src/fpathconf.c b/c/src/exec/libcsupport/src/fpathconf.c index ea2377e15b..f3fb1162d0 100644 --- a/c/src/exec/libcsupport/src/fpathconf.c +++ b/c/src/exec/libcsupport/src/fpathconf.c @@ -26,23 +26,23 @@ long fpathconf( rtems_libio_t *iop; rtems_filesystem_limits_and_options_t *the_limits; + rtems_libio_check_fd(fd); + iop = rtems_libio_iop(fd); + 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 ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the information request. */ - iop = rtems_libio_iop(fd); - rtems_libio_check_fd(fd); - rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ); - the_limits = &iop->pathinfo.mt_entry->pathconf_limits_and_options; switch ( name ) { diff --git a/c/src/exec/libcsupport/src/fsync.c b/c/src/exec/libcsupport/src/fsync.c index a5ed1e99e7..b77c77312c 100644 --- a/c/src/exec/libcsupport/src/fsync.c +++ b/c/src/exec/libcsupport/src/fsync.c @@ -22,22 +22,22 @@ int fsync( { rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + 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 ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the fsync(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); - if ( !iop->handlers->fsync ) set_errno_and_return_minus_one( ENOTSUP ); diff --git a/c/src/exec/libcsupport/src/ftruncate.c b/c/src/exec/libcsupport/src/ftruncate.c index 7fb2286531..5bcb2ea5d8 100644 --- a/c/src/exec/libcsupport/src/ftruncate.c +++ b/c/src/exec/libcsupport/src/ftruncate.c @@ -25,19 +25,20 @@ int ftruncate( rtems_libio_t *iop; rtems_filesystem_location_info_t loc; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + /* * If this is not a file system based entity, it is an error. */ - if ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the ftruncate() request. */ - iop = rtems_libio_iop( fd ); - /* * Make sure we are not working on a directory */ @@ -49,7 +50,6 @@ int ftruncate( if ( (*loc.ops->node_type)( &loc ) == RTEMS_FILESYSTEM_DIRECTORY ) set_errno_and_return_minus_one( EISDIR ); - rtems_libio_check_fd( fd ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); if ( !iop->handlers->ftruncate ) diff --git a/c/src/exec/libcsupport/src/ioctl.c b/c/src/exec/libcsupport/src/ioctl.c index 0aaf0379ae..9284c7f9dc 100644 --- a/c/src/exec/libcsupport/src/ioctl.c +++ b/c/src/exec/libcsupport/src/ioctl.c @@ -26,15 +26,19 @@ int ioctl( rtems_status_code rc; rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + /* * 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 ) ) { + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) { rtems_libio_ioctl_t fp; - fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].ioctl; + fp = rtems_libio_handlers[ + (iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].ioctl; if ( fp == NULL ) set_errno_and_return_minus_one( EBADF ); @@ -45,9 +49,6 @@ int ioctl( * Now process the ioctl(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - if ( !iop->handlers->ioctl ) set_errno_and_return_minus_one( ENOTSUP ); diff --git a/c/src/exec/libcsupport/src/libio.c b/c/src/exec/libcsupport/src/libio.c index e63a4626d4..88aea9b62f 100644 --- a/c/src/exec/libcsupport/src/libio.c +++ b/c/src/exec/libcsupport/src/libio.c @@ -3,9 +3,6 @@ * table of integer style file descriptors used by the low level * POSIX system calls like open(), read, fstat(), etc. * - * This provides the foundation for POSIX compliant IO system calls - * for RTEMS. - * * COPYRIGHT (c) 1989-1998. * On-Line Applications Research Corporation (OAR). * Copyright assigned to U.S. Government, 1994. @@ -18,17 +15,55 @@ */ #include "libio_.h" /* libio_.h pulls in rtems */ +#include +#include /* assoc.h not included by rtems.h */ + +#include /* O_RDONLY, et.al. */ +#include /* O_RDONLY, et.al. */ +#include +#include + +#if ! defined(O_NDELAY) +# if defined(solaris2) +# define O_NDELAY O_NONBLOCK +# elif defined(RTEMS_NEWLIB) +# define O_NDELAY _FNBIO +# endif +#endif + + +#include +#include /* strcmp */ +#include +#include /* calloc() */ + +#include "libio.h" /* libio.h not pulled in by rtems */ + +/* + * File descriptor Table Information + */ + +extern unsigned32 rtems_libio_number_iops; +rtems_id rtems_libio_semaphore; +rtems_libio_t *rtems_libio_iops; +rtems_libio_t *rtems_libio_last_iop; +rtems_libio_t *rtems_libio_iop_freelist; /* - * Global variables used to manage the File Descriptor Table. - * IOP = IO Pointer. + * External I/O Handlers Table + * + * Space for all possible handlers is preallocated + * to speed up dispatch to external handlers. */ -rtems_id rtems_libio_semaphore; -rtems_libio_t *rtems_libio_iops; -rtems_libio_t *rtems_libio_last_iop; rtems_libio_handler_t rtems_libio_handlers[15]; +/* + * Default mode for all files. + */ + +mode_t rtems_filesystem_umask; + /* * rtems_register_libio_handler * @@ -44,8 +79,7 @@ void rtems_register_libio_handler( const rtems_libio_handler_t *handler ) { - int handler_index = rtems_file_descriptor_type_index( handler_flag ); - + int handler_index = (handler_flag >> LIBIO_FLAGS_HANDLER_SHIFT) - 1; if ((handler_index < 0) || (handler_index >= 15)) rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER ); @@ -61,21 +95,22 @@ void rtems_register_libio_handler( void rtems_libio_init( void ) { - rtems_status_code rc; - - /* - * Allocate memory for the IOP Table - */ - - if ( rtems_libio_number_iops > 0 ) { - rtems_libio_iops = - (rtems_libio_t *) calloc(rtems_libio_number_iops, sizeof(rtems_libio_t)); - - if (rtems_libio_iops == NULL) - rtems_fatal_error_occurred( RTEMS_NO_MEMORY ); - - rtems_libio_last_iop = rtems_libio_iops + (rtems_libio_number_iops - 1); - } + rtems_status_code rc; + int i; + rtems_libio_t *iop; + + if (rtems_libio_number_iops > 0) + { + rtems_libio_iops = (rtems_libio_t *) calloc(rtems_libio_number_iops, + sizeof(rtems_libio_t)); + if (rtems_libio_iops == NULL) + rtems_fatal_error_occurred(RTEMS_NO_MEMORY); + + iop = rtems_libio_iop_freelist = rtems_libio_iops; + for (i = 0 ; i < (rtems_libio_number_iops - 1) ; i++, iop++) + iop->data1 = iop + 1; + iop->data1 = NULL; + } /* * Create the binary semaphore used to provide mutual exclusion @@ -157,24 +192,21 @@ rtems_libio_t *rtems_libio_allocate( void ) rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); - for (iop = rtems_libio_iops; iop <= rtems_libio_last_iop; iop++) - if ((iop->flags & LIBIO_FLAGS_OPEN) == 0) { - /* - * Got an IOP -- create a semaphore for it. - */ - - rc = rtems_semaphore_create( - RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops), - 1, - RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY, - RTEMS_NO_PRIORITY, - &iop->sem - ); - if ( rc != RTEMS_SUCCESSFUL ) - goto failed; - - iop->flags = LIBIO_FLAGS_OPEN; - goto done; + if (rtems_libio_iop_freelist) { + iop = rtems_libio_iop_freelist; + rc = rtems_semaphore_create( + RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops), + 1, + RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY, + RTEMS_NO_PRIORITY, + &iop->sem + ); + if (rc != RTEMS_SUCCESSFUL) + goto failed; + rtems_libio_iop_freelist = iop->data1; + iop->data1 = 0; + iop->flags = LIBIO_FLAGS_OPEN; + goto done; } failed: @@ -198,19 +230,20 @@ void rtems_libio_free( { rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); - if (iop->sem) - rtems_semaphore_delete(iop->sem); + if (iop->sem) + rtems_semaphore_delete(iop->sem); - (void) memset(iop, 0, sizeof(*iop)); + iop->data1 = rtems_libio_iop_freelist; + rtems_libio_iop_freelist = iop; - rtems_semaphore_release( rtems_libio_semaphore ); + rtems_semaphore_release(rtems_libio_semaphore); } /* * rtems_libio_is_open_files_in_fs * * This routine scans the entire file descriptor table to determine if the - * are any active file descriptors that refer to the atleast one node in the + * are any active file descriptors that refer to the at least one node in the * file system that we are trying to dismount. * * If there is at least one node in the file system referenced by the mount @@ -225,19 +258,19 @@ int rtems_libio_is_open_files_in_fs( int result = 0; rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); - + /* * Look for any active file descriptor entry. - */ - + */ + for ( iop=rtems_libio_iops ; iop <= rtems_libio_last_iop ; iop++ ) { - + if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) { - + /* * Check if this node is under the file system that we * are trying to dismount. - */ + */ if ( iop->pathinfo.mt_entry == fs_mt_entry ) { result = 1; @@ -247,7 +280,7 @@ int rtems_libio_is_open_files_in_fs( } rtems_semaphore_release( rtems_libio_semaphore ); - + return result; } @@ -256,7 +289,7 @@ int rtems_libio_is_open_files_in_fs( * * This routine scans the entire file descriptor table to determine if the * given file refers to an active file descriptor. - * + * * If the given file is open a 1 is returned, otherwise a 0 is returned. */ @@ -265,22 +298,22 @@ int rtems_libio_is_file_open( ) { rtems_libio_t *iop; - int result=0; + int result=0; rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); /* * Look for any active file descriptor entry. */ - + for ( iop=rtems_libio_iops ; iop <= rtems_libio_last_iop ; iop++ ) { - + if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) { - + /* * Check if this node is under the file system that we * are trying to dismount. - */ + */ if ( iop->pathinfo.node_access == node_access ) { result = 1; @@ -293,3 +326,5 @@ int rtems_libio_is_file_open( return result; } + + diff --git a/c/src/exec/libcsupport/src/lseek.c b/c/src/exec/libcsupport/src/lseek.c index 514f8cd912..cd8046356f 100644 --- a/c/src/exec/libcsupport/src/lseek.c +++ b/c/src/exec/libcsupport/src/lseek.c @@ -24,15 +24,19 @@ off_t lseek( { rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + /* * 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 ) ) { + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) { rtems_libio_lseek_t fp; - fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].lseek; + fp = rtems_libio_handlers[ + (iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].lseek; if ( fp == NULL ) set_errno_and_return_minus_one( EBADF ); @@ -43,9 +47,6 @@ off_t lseek( * Now process the lseek(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - switch ( whence ) { case SEEK_SET: iop->offset = offset; diff --git a/c/src/exec/libcsupport/src/read.c b/c/src/exec/libcsupport/src/read.c index 150fe675ab..1ed6a0bd00 100644 --- a/c/src/exec/libcsupport/src/read.c +++ b/c/src/exec/libcsupport/src/read.c @@ -26,15 +26,22 @@ int read( int rc; /* XXX change to a size_t when prototype is fixed */ rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_buffer( buffer ); + rtems_libio_check_count( count ); + 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 ( rtems_file_descriptor_type( fd ) ) { + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) { rtems_libio_read_t fp; - fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].read; + fp = rtems_libio_handlers[ + (iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].read; if ( fp == NULL ) set_errno_and_return_minus_one( EBADF ); @@ -45,12 +52,6 @@ int read( * Now process the read(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - rtems_libio_check_buffer( buffer ); - rtems_libio_check_count( count ); - rtems_libio_check_permissions( iop, LIBIO_FLAGS_READ ); - if ( !iop->handlers->read ) set_errno_and_return_minus_one( ENOTSUP ); diff --git a/c/src/exec/libcsupport/src/write.c b/c/src/exec/libcsupport/src/write.c index 7e0953bb90..3de21f0d0f 100644 --- a/c/src/exec/libcsupport/src/write.c +++ b/c/src/exec/libcsupport/src/write.c @@ -34,15 +34,22 @@ int write( /* XXX this should return a ssize_t */ rtems_status_code rc; rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_buffer( buffer ); + rtems_libio_check_count( count ); + 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 ( rtems_file_descriptor_type( fd ) ) { + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) { rtems_libio_write_t fp; - fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].write; + fp = rtems_libio_handlers[ + (iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].write; if ( fp == NULL ) set_errno_and_return_minus_one( EBADF ); @@ -53,12 +60,6 @@ int write( /* XXX this should return a ssize_t */ * Now process the write() request. */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - rtems_libio_check_buffer( buffer ); - rtems_libio_check_count( count ); - rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); - if ( !iop->handlers->write ) set_errno_and_return_minus_one( ENOTSUP ); diff --git a/c/src/exec/libnetworking/rtems/rtems_glue.c b/c/src/exec/libnetworking/rtems/rtems_glue.c index f2449831f5..28fb179c22 100644 --- a/c/src/exec/libnetworking/rtems/rtems_glue.c +++ b/c/src/exec/libnetworking/rtems/rtems_glue.c @@ -30,19 +30,6 @@ #include #include -/* - * Events used by networking routines. - * Everything will break if the application - * tries to use these events or if the `sleep' - * events are equal to any of the NETISR * events. - */ -#define SBWAIT_EVENT RTEMS_EVENT_24 -#define SOSLEEP_EVENT RTEMS_EVENT_25 -#define NETISR_IP_EVENT (1 << NETISR_IP) -#define NETISR_ARP_EVENT (1 << NETISR_ARP) -#define NETISR_EVENTS (NETISR_IP_EVENT|NETISR_ARP_EVENT) - - /* * Memory allocation */ @@ -246,7 +233,7 @@ rtems_bsdnet_initialize (void) /* * Register as an external I/O handler */ - rtems_register_libio_handler (RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET, + rtems_register_libio_handler (LIBIO_FLAGS_HANDLER_SOCK, &rtems_bsdnet_io_handler); /* @@ -305,16 +292,9 @@ sbwait(sb) /* * Set this task as the target of the wakeup operation. */ - if (sb->sb_sel.si_pid) - rtems_panic ("Another task is already sleeping on that socket buffer"); rtems_task_ident (RTEMS_SELF, 0, &tid); sb->sb_sel.si_pid = tid; - /* - * Mark the socket buffer as waiting. - */ - sb->sb_flags |= SB_WAIT; - /* * Release the network semaphore. */ @@ -330,12 +310,6 @@ sbwait(sb) */ rtems_bsdnet_semaphore_obtain (); - /* - * Relinquish ownership of the socket buffer - */ - sb->sb_flags &= ~SB_WAIT; - sb->sb_sel.si_pid = 0; - /* * Return the status of the wait. */ @@ -355,9 +329,11 @@ sowakeup(so, sb) register struct socket *so; register struct sockbuf *sb; { - if (sb->sb_flags & SB_WAIT) { - sb->sb_flags &= ~SB_WAIT; - rtems_event_send (sb->sb_sel.si_pid, SBWAIT_EVENT); + rtems_id tid; + + if ((tid = sb->sb_sel.si_pid) != 0) { + sb->sb_sel.si_pid = 0; + rtems_event_send (tid, SBWAIT_EVENT); } } diff --git a/c/src/exec/libnetworking/rtems/rtems_syscall.c b/c/src/exec/libnetworking/rtems/rtems_syscall.c index 93ecd47c6f..63d34bd817 100644 --- a/c/src/exec/libnetworking/rtems/rtems_syscall.c +++ b/c/src/exec/libnetworking/rtems/rtems_syscall.c @@ -25,77 +25,6 @@ #include #include -/* - ********************************************************************* - * Map RTEMS file descriptor to BSD socket * - ********************************************************************* - */ -struct fdsock { - int indexFreeNext; - struct socket *sock; -}; -static struct fdsock *fdsock; -static int fdsockCount; -static int indexFreeHead = -1; - -/* - * Convert an RTEMS file descriptor to a BSD socket pointer. - */ -static struct socket * -fdToSocket (int fd) -{ - int i; - struct socket *s; - - if ((fd < 0) - || (rtems_file_descriptor_type(fd) != RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET) - || ((i = rtems_file_descriptor_base(fd)) >= fdsockCount) - || ((s = fdsock[i].sock) == NULL)) { - errno = EBADF; - return NULL; - } - return s; -} - -/* - * Enlarge the size of the file-descritor/socket pointer map. - */ -static int -enlargeFdMap (void) -{ - struct fdsock *nfdsock; - int i; - - nfdsock = realloc (fdsock, sizeof *fdsock * (fdsockCount + 20)); - if (nfdsock == NULL) { - errno = ENFILE; - return 0; - } - fdsock = nfdsock; - for (i = fdsockCount, fdsockCount += 20 ; i < fdsockCount ; i++) { - fdsock[i].sock = NULL; - fdsock[i].indexFreeNext = indexFreeHead; - indexFreeHead = i; - } - return 1; -} - -/* - * Create a file descriptor for a new socket - */ -static int -makeFd (struct socket *s) -{ - int i; - - if ((indexFreeHead < 0) && !enlargeFdMap ()) - return -1; - i = indexFreeHead; - indexFreeHead = fdsock[i].indexFreeNext; - fdsock[i].sock = s; - return rtems_make_file_descriptor(i,RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET); -} - /* * Package system call argument into mbuf. */ @@ -128,14 +57,14 @@ sockargstombuf (struct mbuf **mp, const void *buf, int buflen, int type) int socket (int domain, int type, int protocol) { - int fd = -1; + int fd; int error; struct socket *so; rtems_bsdnet_semaphore_obtain (); error = socreate(domain, &so, type, protocol, NULL); if (error == 0) { - fd = makeFd (so); + fd = rtems_bsdnet_makeFdForSocket (so); if (fd < 0) soclose (so); } @@ -156,7 +85,7 @@ bind (int s, struct sockaddr *name, int namelen) struct mbuf *nam; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) != NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) { error = sockargstombuf (&nam, name, namelen, MT_SONAME); if (error == 0) { error = sobind (so, nam); @@ -183,7 +112,7 @@ connect (int s, struct sockaddr *name, int namelen) struct mbuf *nam; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -233,7 +162,7 @@ listen (int s, int backlog) struct socket *so; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) != NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) { error = solisten (so, backlog); if (error == 0) ret = 0; @@ -252,7 +181,7 @@ accept (int s, struct sockaddr *name, int *namelen) struct mbuf *nam; rtems_bsdnet_semaphore_obtain (); - if ((head = fdToSocket (s)) == NULL) { + if ((head = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -284,7 +213,7 @@ accept (int s, struct sockaddr *name, int *namelen) TAILQ_REMOVE(&head->so_comp, so, so_list); head->so_qlen--; - fd = makeFd (so); + fd = rtems_bsdnet_makeFdForSocket (so); if (fd < 0) { TAILQ_INSERT_HEAD(&head->so_comp, so, so_list); head->so_qlen++; @@ -325,7 +254,7 @@ sendmsg (int s, const struct msghdr *mp, int flags) int len; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -428,7 +357,7 @@ recvmsg (int s, struct msghdr *mp, int flags) int len; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -547,7 +476,7 @@ setsockopt (int s, int level, int name, const void *val, int len) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -584,7 +513,7 @@ getsockopt (int s, int level, int name, void *aval, int *avalsize) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -626,7 +555,7 @@ getpeersockname (int s, struct sockaddr *name, int *namelen, int pflag) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -676,16 +605,12 @@ rtems_bsdnet_close (int fd) { struct socket *so; int error; - int i; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (fd)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } - i = rtems_file_descriptor_base(fd); - fdsock[i].indexFreeNext = indexFreeHead;; - indexFreeHead = i; error = soclose (so); rtems_bsdnet_semaphore_release (); if (error) { @@ -737,7 +662,7 @@ rtems_bsdnet_ioctl (int fd, unsigned32 command, void *buffer) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (fd)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } diff --git a/c/src/lib/include/rtems/libio.h b/c/src/lib/include/rtems/libio.h index ee0aaf9b7f..740574f303 100644 --- a/c/src/lib/include/rtems/libio.h +++ b/c/src/lib/include/rtems/libio.h @@ -393,12 +393,16 @@ typedef struct { #define LIBIO_FLAGS_NO_DELAY 0x0001 /* return immediately if no data */ #define LIBIO_FLAGS_READ 0x0002 /* reading */ #define LIBIO_FLAGS_WRITE 0x0004 /* writing */ -#define LIBIO_FLAGS_LINE_BUFFERED 0x0008 /* line buffered io (^h, ^u, etc) */ #define LIBIO_FLAGS_OPEN 0x0100 /* device is open */ #define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */ #define LIBIO_FLAGS_CREATE 0x0400 /* create file */ #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) diff --git a/c/src/lib/include/rtems/libio_.h b/c/src/lib/include/rtems/libio_.h index 33a9e7bda5..d595500430 100644 --- a/c/src/lib/include/rtems/libio_.h +++ b/c/src/lib/include/rtems/libio_.h @@ -65,6 +65,7 @@ extern rtems_id rtems_libio_semaphore; extern unsigned32 rtems_libio_number_iops; extern rtems_libio_t *rtems_libio_iops; extern rtems_libio_t *rtems_libio_last_iop; +extern rtems_libio_t *rtems_libio_iop_freelist; /* * External I/O Handlers Table diff --git a/c/src/lib/include/sys/sockio.h b/c/src/lib/include/sys/sockio.h index 03ec16e43a..5e54baffe8 100644 --- a/c/src/lib/include/sys/sockio.h +++ b/c/src/lib/include/sys/sockio.h @@ -83,11 +83,10 @@ #define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) /* set net media */ #define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */ - /* * RTEMS additions for setting/getting `tap' function on incoming packets. */ -#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */ -#define SIOCGIFTAP _IOWR('i', 81, struct ifreq) /* get tap function */ +#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */ +#define SIOCGIFTAP _IOW('i', 81, struct ifreq) /* get tap function */ #endif /* !_SYS_SOCKIO_H_ */ diff --git a/c/src/lib/libc/close.c b/c/src/lib/libc/close.c index 94ddb45c90..0583a36b22 100644 --- a/c/src/lib/libc/close.c +++ b/c/src/lib/libc/close.c @@ -22,17 +22,18 @@ int close( rtems_status_code rc; int status; - if ( rtems_file_descriptor_type( fd ) ) { + rtems_libio_check_fd(fd); + iop = rtems_libio_iop(fd); + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) { int (*fp)(int fd); - fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].close; + fp = rtems_libio_handlers[ + (iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].close; if ( fp == NULL ) set_errno_and_return_minus_one( EBADF ); status = (*fp)( fd ); return status; } - iop = rtems_libio_iop(fd); - rtems_libio_check_fd(fd); if ( !iop->handlers ) set_errno_and_return_minus_one( EBADF ); diff --git a/c/src/lib/libc/fchmod.c b/c/src/lib/libc/fchmod.c index a3ca4507ab..f202a30eb0 100644 --- a/c/src/lib/libc/fchmod.c +++ b/c/src/lib/libc/fchmod.c @@ -27,19 +27,20 @@ int fchmod( { rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + /* * If this is not a file system based entity, it is an error. */ - if ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the fchmod(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); if ( !iop->handlers->fchmod ) diff --git a/c/src/lib/libc/fcntl.c b/c/src/lib/libc/fcntl.c index a538ec1cf9..b327a447ac 100644 --- a/c/src/lib/libc/fcntl.c +++ b/c/src/lib/libc/fcntl.c @@ -32,20 +32,20 @@ int fcntl( va_start( ap, cmd ); + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + /* * If this is not a file system based entity, it is an error. */ - if ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the fcntl(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - /* * This switch should contain all the cases from POSIX. */ diff --git a/c/src/lib/libc/fdatasync.c b/c/src/lib/libc/fdatasync.c index 58a4c4e118..91bff3aaba 100644 --- a/c/src/lib/libc/fdatasync.c +++ b/c/src/lib/libc/fdatasync.c @@ -22,22 +22,22 @@ int fdatasync( { rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + 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 ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the fdatasync(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); - if ( !iop->handlers->fdatasync ) set_errno_and_return_minus_one( ENOTSUP ); diff --git a/c/src/lib/libc/fpathconf.c b/c/src/lib/libc/fpathconf.c index ea2377e15b..f3fb1162d0 100644 --- a/c/src/lib/libc/fpathconf.c +++ b/c/src/lib/libc/fpathconf.c @@ -26,23 +26,23 @@ long fpathconf( rtems_libio_t *iop; rtems_filesystem_limits_and_options_t *the_limits; + rtems_libio_check_fd(fd); + iop = rtems_libio_iop(fd); + 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 ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the information request. */ - iop = rtems_libio_iop(fd); - rtems_libio_check_fd(fd); - rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ); - the_limits = &iop->pathinfo.mt_entry->pathconf_limits_and_options; switch ( name ) { diff --git a/c/src/lib/libc/fsync.c b/c/src/lib/libc/fsync.c index a5ed1e99e7..b77c77312c 100644 --- a/c/src/lib/libc/fsync.c +++ b/c/src/lib/libc/fsync.c @@ -22,22 +22,22 @@ int fsync( { rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + 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 ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the fsync(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); - if ( !iop->handlers->fsync ) set_errno_and_return_minus_one( ENOTSUP ); diff --git a/c/src/lib/libc/ftruncate.c b/c/src/lib/libc/ftruncate.c index 7fb2286531..5bcb2ea5d8 100644 --- a/c/src/lib/libc/ftruncate.c +++ b/c/src/lib/libc/ftruncate.c @@ -25,19 +25,20 @@ int ftruncate( rtems_libio_t *iop; rtems_filesystem_location_info_t loc; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + /* * If this is not a file system based entity, it is an error. */ - if ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the ftruncate() request. */ - iop = rtems_libio_iop( fd ); - /* * Make sure we are not working on a directory */ @@ -49,7 +50,6 @@ int ftruncate( if ( (*loc.ops->node_type)( &loc ) == RTEMS_FILESYSTEM_DIRECTORY ) set_errno_and_return_minus_one( EISDIR ); - rtems_libio_check_fd( fd ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); if ( !iop->handlers->ftruncate ) diff --git a/c/src/lib/libc/ioctl.c b/c/src/lib/libc/ioctl.c index 0aaf0379ae..9284c7f9dc 100644 --- a/c/src/lib/libc/ioctl.c +++ b/c/src/lib/libc/ioctl.c @@ -26,15 +26,19 @@ int ioctl( rtems_status_code rc; rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + /* * 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 ) ) { + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) { rtems_libio_ioctl_t fp; - fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].ioctl; + fp = rtems_libio_handlers[ + (iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].ioctl; if ( fp == NULL ) set_errno_and_return_minus_one( EBADF ); @@ -45,9 +49,6 @@ int ioctl( * Now process the ioctl(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - if ( !iop->handlers->ioctl ) set_errno_and_return_minus_one( ENOTSUP ); diff --git a/c/src/lib/libc/libio.c b/c/src/lib/libc/libio.c index e63a4626d4..88aea9b62f 100644 --- a/c/src/lib/libc/libio.c +++ b/c/src/lib/libc/libio.c @@ -3,9 +3,6 @@ * table of integer style file descriptors used by the low level * POSIX system calls like open(), read, fstat(), etc. * - * This provides the foundation for POSIX compliant IO system calls - * for RTEMS. - * * COPYRIGHT (c) 1989-1998. * On-Line Applications Research Corporation (OAR). * Copyright assigned to U.S. Government, 1994. @@ -18,17 +15,55 @@ */ #include "libio_.h" /* libio_.h pulls in rtems */ +#include +#include /* assoc.h not included by rtems.h */ + +#include /* O_RDONLY, et.al. */ +#include /* O_RDONLY, et.al. */ +#include +#include + +#if ! defined(O_NDELAY) +# if defined(solaris2) +# define O_NDELAY O_NONBLOCK +# elif defined(RTEMS_NEWLIB) +# define O_NDELAY _FNBIO +# endif +#endif + + +#include +#include /* strcmp */ +#include +#include /* calloc() */ + +#include "libio.h" /* libio.h not pulled in by rtems */ + +/* + * File descriptor Table Information + */ + +extern unsigned32 rtems_libio_number_iops; +rtems_id rtems_libio_semaphore; +rtems_libio_t *rtems_libio_iops; +rtems_libio_t *rtems_libio_last_iop; +rtems_libio_t *rtems_libio_iop_freelist; /* - * Global variables used to manage the File Descriptor Table. - * IOP = IO Pointer. + * External I/O Handlers Table + * + * Space for all possible handlers is preallocated + * to speed up dispatch to external handlers. */ -rtems_id rtems_libio_semaphore; -rtems_libio_t *rtems_libio_iops; -rtems_libio_t *rtems_libio_last_iop; rtems_libio_handler_t rtems_libio_handlers[15]; +/* + * Default mode for all files. + */ + +mode_t rtems_filesystem_umask; + /* * rtems_register_libio_handler * @@ -44,8 +79,7 @@ void rtems_register_libio_handler( const rtems_libio_handler_t *handler ) { - int handler_index = rtems_file_descriptor_type_index( handler_flag ); - + int handler_index = (handler_flag >> LIBIO_FLAGS_HANDLER_SHIFT) - 1; if ((handler_index < 0) || (handler_index >= 15)) rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER ); @@ -61,21 +95,22 @@ void rtems_register_libio_handler( void rtems_libio_init( void ) { - rtems_status_code rc; - - /* - * Allocate memory for the IOP Table - */ - - if ( rtems_libio_number_iops > 0 ) { - rtems_libio_iops = - (rtems_libio_t *) calloc(rtems_libio_number_iops, sizeof(rtems_libio_t)); - - if (rtems_libio_iops == NULL) - rtems_fatal_error_occurred( RTEMS_NO_MEMORY ); - - rtems_libio_last_iop = rtems_libio_iops + (rtems_libio_number_iops - 1); - } + rtems_status_code rc; + int i; + rtems_libio_t *iop; + + if (rtems_libio_number_iops > 0) + { + rtems_libio_iops = (rtems_libio_t *) calloc(rtems_libio_number_iops, + sizeof(rtems_libio_t)); + if (rtems_libio_iops == NULL) + rtems_fatal_error_occurred(RTEMS_NO_MEMORY); + + iop = rtems_libio_iop_freelist = rtems_libio_iops; + for (i = 0 ; i < (rtems_libio_number_iops - 1) ; i++, iop++) + iop->data1 = iop + 1; + iop->data1 = NULL; + } /* * Create the binary semaphore used to provide mutual exclusion @@ -157,24 +192,21 @@ rtems_libio_t *rtems_libio_allocate( void ) rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); - for (iop = rtems_libio_iops; iop <= rtems_libio_last_iop; iop++) - if ((iop->flags & LIBIO_FLAGS_OPEN) == 0) { - /* - * Got an IOP -- create a semaphore for it. - */ - - rc = rtems_semaphore_create( - RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops), - 1, - RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY, - RTEMS_NO_PRIORITY, - &iop->sem - ); - if ( rc != RTEMS_SUCCESSFUL ) - goto failed; - - iop->flags = LIBIO_FLAGS_OPEN; - goto done; + if (rtems_libio_iop_freelist) { + iop = rtems_libio_iop_freelist; + rc = rtems_semaphore_create( + RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops), + 1, + RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY, + RTEMS_NO_PRIORITY, + &iop->sem + ); + if (rc != RTEMS_SUCCESSFUL) + goto failed; + rtems_libio_iop_freelist = iop->data1; + iop->data1 = 0; + iop->flags = LIBIO_FLAGS_OPEN; + goto done; } failed: @@ -198,19 +230,20 @@ void rtems_libio_free( { rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); - if (iop->sem) - rtems_semaphore_delete(iop->sem); + if (iop->sem) + rtems_semaphore_delete(iop->sem); - (void) memset(iop, 0, sizeof(*iop)); + iop->data1 = rtems_libio_iop_freelist; + rtems_libio_iop_freelist = iop; - rtems_semaphore_release( rtems_libio_semaphore ); + rtems_semaphore_release(rtems_libio_semaphore); } /* * rtems_libio_is_open_files_in_fs * * This routine scans the entire file descriptor table to determine if the - * are any active file descriptors that refer to the atleast one node in the + * are any active file descriptors that refer to the at least one node in the * file system that we are trying to dismount. * * If there is at least one node in the file system referenced by the mount @@ -225,19 +258,19 @@ int rtems_libio_is_open_files_in_fs( int result = 0; rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); - + /* * Look for any active file descriptor entry. - */ - + */ + for ( iop=rtems_libio_iops ; iop <= rtems_libio_last_iop ; iop++ ) { - + if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) { - + /* * Check if this node is under the file system that we * are trying to dismount. - */ + */ if ( iop->pathinfo.mt_entry == fs_mt_entry ) { result = 1; @@ -247,7 +280,7 @@ int rtems_libio_is_open_files_in_fs( } rtems_semaphore_release( rtems_libio_semaphore ); - + return result; } @@ -256,7 +289,7 @@ int rtems_libio_is_open_files_in_fs( * * This routine scans the entire file descriptor table to determine if the * given file refers to an active file descriptor. - * + * * If the given file is open a 1 is returned, otherwise a 0 is returned. */ @@ -265,22 +298,22 @@ int rtems_libio_is_file_open( ) { rtems_libio_t *iop; - int result=0; + int result=0; rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); /* * Look for any active file descriptor entry. */ - + for ( iop=rtems_libio_iops ; iop <= rtems_libio_last_iop ; iop++ ) { - + if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) { - + /* * Check if this node is under the file system that we * are trying to dismount. - */ + */ if ( iop->pathinfo.node_access == node_access ) { result = 1; @@ -293,3 +326,5 @@ int rtems_libio_is_file_open( return result; } + + diff --git a/c/src/lib/libc/libio.h b/c/src/lib/libc/libio.h index ee0aaf9b7f..740574f303 100644 --- a/c/src/lib/libc/libio.h +++ b/c/src/lib/libc/libio.h @@ -393,12 +393,16 @@ typedef struct { #define LIBIO_FLAGS_NO_DELAY 0x0001 /* return immediately if no data */ #define LIBIO_FLAGS_READ 0x0002 /* reading */ #define LIBIO_FLAGS_WRITE 0x0004 /* writing */ -#define LIBIO_FLAGS_LINE_BUFFERED 0x0008 /* line buffered io (^h, ^u, etc) */ #define LIBIO_FLAGS_OPEN 0x0100 /* device is open */ #define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */ #define LIBIO_FLAGS_CREATE 0x0400 /* create file */ #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) diff --git a/c/src/lib/libc/libio_.h b/c/src/lib/libc/libio_.h index 33a9e7bda5..d595500430 100644 --- a/c/src/lib/libc/libio_.h +++ b/c/src/lib/libc/libio_.h @@ -65,6 +65,7 @@ extern rtems_id rtems_libio_semaphore; extern unsigned32 rtems_libio_number_iops; extern rtems_libio_t *rtems_libio_iops; extern rtems_libio_t *rtems_libio_last_iop; +extern rtems_libio_t *rtems_libio_iop_freelist; /* * External I/O Handlers Table diff --git a/c/src/lib/libc/lseek.c b/c/src/lib/libc/lseek.c index 514f8cd912..cd8046356f 100644 --- a/c/src/lib/libc/lseek.c +++ b/c/src/lib/libc/lseek.c @@ -24,15 +24,19 @@ off_t lseek( { rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + /* * 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 ) ) { + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) { rtems_libio_lseek_t fp; - fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].lseek; + fp = rtems_libio_handlers[ + (iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].lseek; if ( fp == NULL ) set_errno_and_return_minus_one( EBADF ); @@ -43,9 +47,6 @@ off_t lseek( * Now process the lseek(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - switch ( whence ) { case SEEK_SET: iop->offset = offset; diff --git a/c/src/lib/libc/read.c b/c/src/lib/libc/read.c index 150fe675ab..1ed6a0bd00 100644 --- a/c/src/lib/libc/read.c +++ b/c/src/lib/libc/read.c @@ -26,15 +26,22 @@ int read( int rc; /* XXX change to a size_t when prototype is fixed */ rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_buffer( buffer ); + rtems_libio_check_count( count ); + 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 ( rtems_file_descriptor_type( fd ) ) { + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) { rtems_libio_read_t fp; - fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].read; + fp = rtems_libio_handlers[ + (iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].read; if ( fp == NULL ) set_errno_and_return_minus_one( EBADF ); @@ -45,12 +52,6 @@ int read( * Now process the read(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - rtems_libio_check_buffer( buffer ); - rtems_libio_check_count( count ); - rtems_libio_check_permissions( iop, LIBIO_FLAGS_READ ); - if ( !iop->handlers->read ) set_errno_and_return_minus_one( ENOTSUP ); diff --git a/c/src/lib/libc/write.c b/c/src/lib/libc/write.c index 7e0953bb90..3de21f0d0f 100644 --- a/c/src/lib/libc/write.c +++ b/c/src/lib/libc/write.c @@ -34,15 +34,22 @@ int write( /* XXX this should return a ssize_t */ rtems_status_code rc; rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_buffer( buffer ); + rtems_libio_check_count( count ); + 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 ( rtems_file_descriptor_type( fd ) ) { + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) { rtems_libio_write_t fp; - fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].write; + fp = rtems_libio_handlers[ + (iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].write; if ( fp == NULL ) set_errno_and_return_minus_one( EBADF ); @@ -53,12 +60,6 @@ int write( /* XXX this should return a ssize_t */ * Now process the write() request. */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - rtems_libio_check_buffer( buffer ); - rtems_libio_check_count( count ); - rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); - if ( !iop->handlers->write ) set_errno_and_return_minus_one( ENOTSUP ); diff --git a/c/src/lib/libnetworking/rtems/Makefile.in b/c/src/lib/libnetworking/rtems/Makefile.in index 038fb5c68e..68d89a9fd0 100644 --- a/c/src/lib/libnetworking/rtems/Makefile.in +++ b/c/src/lib/libnetworking/rtems/Makefile.in @@ -16,7 +16,7 @@ C_PIECES=sghostname issetugid \ rtems_glue rtems_syscall rtems_bootp \ rtems_showmbuf rtems_showroute \ rtems_showifstat rtems_showipstat rtems_showicmpstat \ - rtems_showtcpstat rtems_showudpstat + rtems_showtcpstat rtems_showudpstat rtems_select C_FILES=$(C_PIECES:%=%.c) C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) diff --git a/c/src/lib/libnetworking/rtems/rtems_glue.c b/c/src/lib/libnetworking/rtems/rtems_glue.c index f2449831f5..28fb179c22 100644 --- a/c/src/lib/libnetworking/rtems/rtems_glue.c +++ b/c/src/lib/libnetworking/rtems/rtems_glue.c @@ -30,19 +30,6 @@ #include #include -/* - * Events used by networking routines. - * Everything will break if the application - * tries to use these events or if the `sleep' - * events are equal to any of the NETISR * events. - */ -#define SBWAIT_EVENT RTEMS_EVENT_24 -#define SOSLEEP_EVENT RTEMS_EVENT_25 -#define NETISR_IP_EVENT (1 << NETISR_IP) -#define NETISR_ARP_EVENT (1 << NETISR_ARP) -#define NETISR_EVENTS (NETISR_IP_EVENT|NETISR_ARP_EVENT) - - /* * Memory allocation */ @@ -246,7 +233,7 @@ rtems_bsdnet_initialize (void) /* * Register as an external I/O handler */ - rtems_register_libio_handler (RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET, + rtems_register_libio_handler (LIBIO_FLAGS_HANDLER_SOCK, &rtems_bsdnet_io_handler); /* @@ -305,16 +292,9 @@ sbwait(sb) /* * Set this task as the target of the wakeup operation. */ - if (sb->sb_sel.si_pid) - rtems_panic ("Another task is already sleeping on that socket buffer"); rtems_task_ident (RTEMS_SELF, 0, &tid); sb->sb_sel.si_pid = tid; - /* - * Mark the socket buffer as waiting. - */ - sb->sb_flags |= SB_WAIT; - /* * Release the network semaphore. */ @@ -330,12 +310,6 @@ sbwait(sb) */ rtems_bsdnet_semaphore_obtain (); - /* - * Relinquish ownership of the socket buffer - */ - sb->sb_flags &= ~SB_WAIT; - sb->sb_sel.si_pid = 0; - /* * Return the status of the wait. */ @@ -355,9 +329,11 @@ sowakeup(so, sb) register struct socket *so; register struct sockbuf *sb; { - if (sb->sb_flags & SB_WAIT) { - sb->sb_flags &= ~SB_WAIT; - rtems_event_send (sb->sb_sel.si_pid, SBWAIT_EVENT); + rtems_id tid; + + if ((tid = sb->sb_sel.si_pid) != 0) { + sb->sb_sel.si_pid = 0; + rtems_event_send (tid, SBWAIT_EVENT); } } diff --git a/c/src/lib/libnetworking/rtems/rtems_syscall.c b/c/src/lib/libnetworking/rtems/rtems_syscall.c index 93ecd47c6f..63d34bd817 100644 --- a/c/src/lib/libnetworking/rtems/rtems_syscall.c +++ b/c/src/lib/libnetworking/rtems/rtems_syscall.c @@ -25,77 +25,6 @@ #include #include -/* - ********************************************************************* - * Map RTEMS file descriptor to BSD socket * - ********************************************************************* - */ -struct fdsock { - int indexFreeNext; - struct socket *sock; -}; -static struct fdsock *fdsock; -static int fdsockCount; -static int indexFreeHead = -1; - -/* - * Convert an RTEMS file descriptor to a BSD socket pointer. - */ -static struct socket * -fdToSocket (int fd) -{ - int i; - struct socket *s; - - if ((fd < 0) - || (rtems_file_descriptor_type(fd) != RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET) - || ((i = rtems_file_descriptor_base(fd)) >= fdsockCount) - || ((s = fdsock[i].sock) == NULL)) { - errno = EBADF; - return NULL; - } - return s; -} - -/* - * Enlarge the size of the file-descritor/socket pointer map. - */ -static int -enlargeFdMap (void) -{ - struct fdsock *nfdsock; - int i; - - nfdsock = realloc (fdsock, sizeof *fdsock * (fdsockCount + 20)); - if (nfdsock == NULL) { - errno = ENFILE; - return 0; - } - fdsock = nfdsock; - for (i = fdsockCount, fdsockCount += 20 ; i < fdsockCount ; i++) { - fdsock[i].sock = NULL; - fdsock[i].indexFreeNext = indexFreeHead; - indexFreeHead = i; - } - return 1; -} - -/* - * Create a file descriptor for a new socket - */ -static int -makeFd (struct socket *s) -{ - int i; - - if ((indexFreeHead < 0) && !enlargeFdMap ()) - return -1; - i = indexFreeHead; - indexFreeHead = fdsock[i].indexFreeNext; - fdsock[i].sock = s; - return rtems_make_file_descriptor(i,RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET); -} - /* * Package system call argument into mbuf. */ @@ -128,14 +57,14 @@ sockargstombuf (struct mbuf **mp, const void *buf, int buflen, int type) int socket (int domain, int type, int protocol) { - int fd = -1; + int fd; int error; struct socket *so; rtems_bsdnet_semaphore_obtain (); error = socreate(domain, &so, type, protocol, NULL); if (error == 0) { - fd = makeFd (so); + fd = rtems_bsdnet_makeFdForSocket (so); if (fd < 0) soclose (so); } @@ -156,7 +85,7 @@ bind (int s, struct sockaddr *name, int namelen) struct mbuf *nam; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) != NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) { error = sockargstombuf (&nam, name, namelen, MT_SONAME); if (error == 0) { error = sobind (so, nam); @@ -183,7 +112,7 @@ connect (int s, struct sockaddr *name, int namelen) struct mbuf *nam; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -233,7 +162,7 @@ listen (int s, int backlog) struct socket *so; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) != NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) { error = solisten (so, backlog); if (error == 0) ret = 0; @@ -252,7 +181,7 @@ accept (int s, struct sockaddr *name, int *namelen) struct mbuf *nam; rtems_bsdnet_semaphore_obtain (); - if ((head = fdToSocket (s)) == NULL) { + if ((head = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -284,7 +213,7 @@ accept (int s, struct sockaddr *name, int *namelen) TAILQ_REMOVE(&head->so_comp, so, so_list); head->so_qlen--; - fd = makeFd (so); + fd = rtems_bsdnet_makeFdForSocket (so); if (fd < 0) { TAILQ_INSERT_HEAD(&head->so_comp, so, so_list); head->so_qlen++; @@ -325,7 +254,7 @@ sendmsg (int s, const struct msghdr *mp, int flags) int len; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -428,7 +357,7 @@ recvmsg (int s, struct msghdr *mp, int flags) int len; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -547,7 +476,7 @@ setsockopt (int s, int level, int name, const void *val, int len) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -584,7 +513,7 @@ getsockopt (int s, int level, int name, void *aval, int *avalsize) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -626,7 +555,7 @@ getpeersockname (int s, struct sockaddr *name, int *namelen, int pflag) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -676,16 +605,12 @@ rtems_bsdnet_close (int fd) { struct socket *so; int error; - int i; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (fd)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } - i = rtems_file_descriptor_base(fd); - fdsock[i].indexFreeNext = indexFreeHead;; - indexFreeHead = i; error = soclose (so); rtems_bsdnet_semaphore_release (); if (error) { @@ -737,7 +662,7 @@ rtems_bsdnet_ioctl (int fd, unsigned32 command, void *buffer) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (fd)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } diff --git a/c/src/lib/libnetworking/sys/sockio.h b/c/src/lib/libnetworking/sys/sockio.h index 03ec16e43a..5e54baffe8 100644 --- a/c/src/lib/libnetworking/sys/sockio.h +++ b/c/src/lib/libnetworking/sys/sockio.h @@ -83,11 +83,10 @@ #define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) /* set net media */ #define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */ - /* * RTEMS additions for setting/getting `tap' function on incoming packets. */ -#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */ -#define SIOCGIFTAP _IOWR('i', 81, struct ifreq) /* get tap function */ +#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */ +#define SIOCGIFTAP _IOW('i', 81, struct ifreq) /* get tap function */ #endif /* !_SYS_SOCKIO_H_ */ diff --git a/c/src/libnetworking/rtems/Makefile.in b/c/src/libnetworking/rtems/Makefile.in index 038fb5c68e..68d89a9fd0 100644 --- a/c/src/libnetworking/rtems/Makefile.in +++ b/c/src/libnetworking/rtems/Makefile.in @@ -16,7 +16,7 @@ C_PIECES=sghostname issetugid \ rtems_glue rtems_syscall rtems_bootp \ rtems_showmbuf rtems_showroute \ rtems_showifstat rtems_showipstat rtems_showicmpstat \ - rtems_showtcpstat rtems_showudpstat + rtems_showtcpstat rtems_showudpstat rtems_select C_FILES=$(C_PIECES:%=%.c) C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) diff --git a/c/src/libnetworking/rtems/rtems_glue.c b/c/src/libnetworking/rtems/rtems_glue.c index f2449831f5..28fb179c22 100644 --- a/c/src/libnetworking/rtems/rtems_glue.c +++ b/c/src/libnetworking/rtems/rtems_glue.c @@ -30,19 +30,6 @@ #include #include -/* - * Events used by networking routines. - * Everything will break if the application - * tries to use these events or if the `sleep' - * events are equal to any of the NETISR * events. - */ -#define SBWAIT_EVENT RTEMS_EVENT_24 -#define SOSLEEP_EVENT RTEMS_EVENT_25 -#define NETISR_IP_EVENT (1 << NETISR_IP) -#define NETISR_ARP_EVENT (1 << NETISR_ARP) -#define NETISR_EVENTS (NETISR_IP_EVENT|NETISR_ARP_EVENT) - - /* * Memory allocation */ @@ -246,7 +233,7 @@ rtems_bsdnet_initialize (void) /* * Register as an external I/O handler */ - rtems_register_libio_handler (RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET, + rtems_register_libio_handler (LIBIO_FLAGS_HANDLER_SOCK, &rtems_bsdnet_io_handler); /* @@ -305,16 +292,9 @@ sbwait(sb) /* * Set this task as the target of the wakeup operation. */ - if (sb->sb_sel.si_pid) - rtems_panic ("Another task is already sleeping on that socket buffer"); rtems_task_ident (RTEMS_SELF, 0, &tid); sb->sb_sel.si_pid = tid; - /* - * Mark the socket buffer as waiting. - */ - sb->sb_flags |= SB_WAIT; - /* * Release the network semaphore. */ @@ -330,12 +310,6 @@ sbwait(sb) */ rtems_bsdnet_semaphore_obtain (); - /* - * Relinquish ownership of the socket buffer - */ - sb->sb_flags &= ~SB_WAIT; - sb->sb_sel.si_pid = 0; - /* * Return the status of the wait. */ @@ -355,9 +329,11 @@ sowakeup(so, sb) register struct socket *so; register struct sockbuf *sb; { - if (sb->sb_flags & SB_WAIT) { - sb->sb_flags &= ~SB_WAIT; - rtems_event_send (sb->sb_sel.si_pid, SBWAIT_EVENT); + rtems_id tid; + + if ((tid = sb->sb_sel.si_pid) != 0) { + sb->sb_sel.si_pid = 0; + rtems_event_send (tid, SBWAIT_EVENT); } } diff --git a/c/src/libnetworking/rtems/rtems_syscall.c b/c/src/libnetworking/rtems/rtems_syscall.c index 93ecd47c6f..63d34bd817 100644 --- a/c/src/libnetworking/rtems/rtems_syscall.c +++ b/c/src/libnetworking/rtems/rtems_syscall.c @@ -25,77 +25,6 @@ #include #include -/* - ********************************************************************* - * Map RTEMS file descriptor to BSD socket * - ********************************************************************* - */ -struct fdsock { - int indexFreeNext; - struct socket *sock; -}; -static struct fdsock *fdsock; -static int fdsockCount; -static int indexFreeHead = -1; - -/* - * Convert an RTEMS file descriptor to a BSD socket pointer. - */ -static struct socket * -fdToSocket (int fd) -{ - int i; - struct socket *s; - - if ((fd < 0) - || (rtems_file_descriptor_type(fd) != RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET) - || ((i = rtems_file_descriptor_base(fd)) >= fdsockCount) - || ((s = fdsock[i].sock) == NULL)) { - errno = EBADF; - return NULL; - } - return s; -} - -/* - * Enlarge the size of the file-descritor/socket pointer map. - */ -static int -enlargeFdMap (void) -{ - struct fdsock *nfdsock; - int i; - - nfdsock = realloc (fdsock, sizeof *fdsock * (fdsockCount + 20)); - if (nfdsock == NULL) { - errno = ENFILE; - return 0; - } - fdsock = nfdsock; - for (i = fdsockCount, fdsockCount += 20 ; i < fdsockCount ; i++) { - fdsock[i].sock = NULL; - fdsock[i].indexFreeNext = indexFreeHead; - indexFreeHead = i; - } - return 1; -} - -/* - * Create a file descriptor for a new socket - */ -static int -makeFd (struct socket *s) -{ - int i; - - if ((indexFreeHead < 0) && !enlargeFdMap ()) - return -1; - i = indexFreeHead; - indexFreeHead = fdsock[i].indexFreeNext; - fdsock[i].sock = s; - return rtems_make_file_descriptor(i,RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET); -} - /* * Package system call argument into mbuf. */ @@ -128,14 +57,14 @@ sockargstombuf (struct mbuf **mp, const void *buf, int buflen, int type) int socket (int domain, int type, int protocol) { - int fd = -1; + int fd; int error; struct socket *so; rtems_bsdnet_semaphore_obtain (); error = socreate(domain, &so, type, protocol, NULL); if (error == 0) { - fd = makeFd (so); + fd = rtems_bsdnet_makeFdForSocket (so); if (fd < 0) soclose (so); } @@ -156,7 +85,7 @@ bind (int s, struct sockaddr *name, int namelen) struct mbuf *nam; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) != NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) { error = sockargstombuf (&nam, name, namelen, MT_SONAME); if (error == 0) { error = sobind (so, nam); @@ -183,7 +112,7 @@ connect (int s, struct sockaddr *name, int namelen) struct mbuf *nam; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -233,7 +162,7 @@ listen (int s, int backlog) struct socket *so; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) != NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) { error = solisten (so, backlog); if (error == 0) ret = 0; @@ -252,7 +181,7 @@ accept (int s, struct sockaddr *name, int *namelen) struct mbuf *nam; rtems_bsdnet_semaphore_obtain (); - if ((head = fdToSocket (s)) == NULL) { + if ((head = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -284,7 +213,7 @@ accept (int s, struct sockaddr *name, int *namelen) TAILQ_REMOVE(&head->so_comp, so, so_list); head->so_qlen--; - fd = makeFd (so); + fd = rtems_bsdnet_makeFdForSocket (so); if (fd < 0) { TAILQ_INSERT_HEAD(&head->so_comp, so, so_list); head->so_qlen++; @@ -325,7 +254,7 @@ sendmsg (int s, const struct msghdr *mp, int flags) int len; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -428,7 +357,7 @@ recvmsg (int s, struct msghdr *mp, int flags) int len; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -547,7 +476,7 @@ setsockopt (int s, int level, int name, const void *val, int len) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -584,7 +513,7 @@ getsockopt (int s, int level, int name, void *aval, int *avalsize) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -626,7 +555,7 @@ getpeersockname (int s, struct sockaddr *name, int *namelen, int pflag) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -676,16 +605,12 @@ rtems_bsdnet_close (int fd) { struct socket *so; int error; - int i; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (fd)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } - i = rtems_file_descriptor_base(fd); - fdsock[i].indexFreeNext = indexFreeHead;; - indexFreeHead = i; error = soclose (so); rtems_bsdnet_semaphore_release (); if (error) { @@ -737,7 +662,7 @@ rtems_bsdnet_ioctl (int fd, unsigned32 command, void *buffer) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (fd)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } diff --git a/c/src/libnetworking/sys/sockio.h b/c/src/libnetworking/sys/sockio.h index 03ec16e43a..5e54baffe8 100644 --- a/c/src/libnetworking/sys/sockio.h +++ b/c/src/libnetworking/sys/sockio.h @@ -83,11 +83,10 @@ #define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) /* set net media */ #define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */ - /* * RTEMS additions for setting/getting `tap' function on incoming packets. */ -#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */ -#define SIOCGIFTAP _IOWR('i', 81, struct ifreq) /* get tap function */ +#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */ +#define SIOCGIFTAP _IOW('i', 81, struct ifreq) /* get tap function */ #endif /* !_SYS_SOCKIO_H_ */ diff --git a/configure b/configure index c54cb6bf1a..3d59d8f300 100644 --- a/configure +++ b/configure @@ -806,7 +806,7 @@ case "${enableval}" in *) { echo "configure: error: bad value ${enableval} for enable-rdbg option" 1>&2; exit 1; } ;; esac else - RTEMS_HAS_RDBG=yes + RTEMS_HAS_RDBG=no fi diff --git a/configure.in b/configure.in index 36d1dc17f6..3603647396 100644 --- a/configure.in +++ b/configure.in @@ -49,7 +49,7 @@ AC_ARG_ENABLE(rdbg, \ yes) RTEMS_HAS_RDBG=yes ;; no) RTEMS_HAS_RDBG=no ;; *) AC_MSG_ERROR(bad value ${enableval} for enable-rdbg option) ;; -esac],[RTEMS_HAS_RDBG=yes]) +esac],[RTEMS_HAS_RDBG=no]) AC_ARG_ENABLE(rtems-inlines, \ [ --enable-rtems-inlines enable RTEMS inline functions (use macros)], \ diff --git a/cpukit/include/rtems/libio_.h b/cpukit/include/rtems/libio_.h index 33a9e7bda5..d595500430 100644 --- a/cpukit/include/rtems/libio_.h +++ b/cpukit/include/rtems/libio_.h @@ -65,6 +65,7 @@ extern rtems_id rtems_libio_semaphore; extern unsigned32 rtems_libio_number_iops; extern rtems_libio_t *rtems_libio_iops; extern rtems_libio_t *rtems_libio_last_iop; +extern rtems_libio_t *rtems_libio_iop_freelist; /* * External I/O Handlers Table diff --git a/cpukit/libcsupport/include/rtems/libio.h b/cpukit/libcsupport/include/rtems/libio.h index ee0aaf9b7f..740574f303 100644 --- a/cpukit/libcsupport/include/rtems/libio.h +++ b/cpukit/libcsupport/include/rtems/libio.h @@ -393,12 +393,16 @@ typedef struct { #define LIBIO_FLAGS_NO_DELAY 0x0001 /* return immediately if no data */ #define LIBIO_FLAGS_READ 0x0002 /* reading */ #define LIBIO_FLAGS_WRITE 0x0004 /* writing */ -#define LIBIO_FLAGS_LINE_BUFFERED 0x0008 /* line buffered io (^h, ^u, etc) */ #define LIBIO_FLAGS_OPEN 0x0100 /* device is open */ #define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */ #define LIBIO_FLAGS_CREATE 0x0400 /* create file */ #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) diff --git a/cpukit/libcsupport/include/rtems/libio_.h b/cpukit/libcsupport/include/rtems/libio_.h index 33a9e7bda5..d595500430 100644 --- a/cpukit/libcsupport/include/rtems/libio_.h +++ b/cpukit/libcsupport/include/rtems/libio_.h @@ -65,6 +65,7 @@ extern rtems_id rtems_libio_semaphore; extern unsigned32 rtems_libio_number_iops; extern rtems_libio_t *rtems_libio_iops; extern rtems_libio_t *rtems_libio_last_iop; +extern rtems_libio_t *rtems_libio_iop_freelist; /* * External I/O Handlers Table diff --git a/cpukit/libcsupport/include/sys/sockio.h b/cpukit/libcsupport/include/sys/sockio.h index 03ec16e43a..5e54baffe8 100644 --- a/cpukit/libcsupport/include/sys/sockio.h +++ b/cpukit/libcsupport/include/sys/sockio.h @@ -83,11 +83,10 @@ #define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) /* set net media */ #define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */ - /* * RTEMS additions for setting/getting `tap' function on incoming packets. */ -#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */ -#define SIOCGIFTAP _IOWR('i', 81, struct ifreq) /* get tap function */ +#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */ +#define SIOCGIFTAP _IOW('i', 81, struct ifreq) /* get tap function */ #endif /* !_SYS_SOCKIO_H_ */ diff --git a/cpukit/libcsupport/src/close.c b/cpukit/libcsupport/src/close.c index 94ddb45c90..0583a36b22 100644 --- a/cpukit/libcsupport/src/close.c +++ b/cpukit/libcsupport/src/close.c @@ -22,17 +22,18 @@ int close( rtems_status_code rc; int status; - if ( rtems_file_descriptor_type( fd ) ) { + rtems_libio_check_fd(fd); + iop = rtems_libio_iop(fd); + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) { int (*fp)(int fd); - fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].close; + fp = rtems_libio_handlers[ + (iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].close; if ( fp == NULL ) set_errno_and_return_minus_one( EBADF ); status = (*fp)( fd ); return status; } - iop = rtems_libio_iop(fd); - rtems_libio_check_fd(fd); if ( !iop->handlers ) set_errno_and_return_minus_one( EBADF ); diff --git a/cpukit/libcsupport/src/fchmod.c b/cpukit/libcsupport/src/fchmod.c index a3ca4507ab..f202a30eb0 100644 --- a/cpukit/libcsupport/src/fchmod.c +++ b/cpukit/libcsupport/src/fchmod.c @@ -27,19 +27,20 @@ int fchmod( { rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + /* * If this is not a file system based entity, it is an error. */ - if ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the fchmod(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); if ( !iop->handlers->fchmod ) diff --git a/cpukit/libcsupport/src/fcntl.c b/cpukit/libcsupport/src/fcntl.c index a538ec1cf9..b327a447ac 100644 --- a/cpukit/libcsupport/src/fcntl.c +++ b/cpukit/libcsupport/src/fcntl.c @@ -32,20 +32,20 @@ int fcntl( va_start( ap, cmd ); + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + /* * If this is not a file system based entity, it is an error. */ - if ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the fcntl(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - /* * This switch should contain all the cases from POSIX. */ diff --git a/cpukit/libcsupport/src/fdatasync.c b/cpukit/libcsupport/src/fdatasync.c index 58a4c4e118..91bff3aaba 100644 --- a/cpukit/libcsupport/src/fdatasync.c +++ b/cpukit/libcsupport/src/fdatasync.c @@ -22,22 +22,22 @@ int fdatasync( { rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + 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 ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the fdatasync(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); - if ( !iop->handlers->fdatasync ) set_errno_and_return_minus_one( ENOTSUP ); diff --git a/cpukit/libcsupport/src/fpathconf.c b/cpukit/libcsupport/src/fpathconf.c index ea2377e15b..f3fb1162d0 100644 --- a/cpukit/libcsupport/src/fpathconf.c +++ b/cpukit/libcsupport/src/fpathconf.c @@ -26,23 +26,23 @@ long fpathconf( rtems_libio_t *iop; rtems_filesystem_limits_and_options_t *the_limits; + rtems_libio_check_fd(fd); + iop = rtems_libio_iop(fd); + 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 ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the information request. */ - iop = rtems_libio_iop(fd); - rtems_libio_check_fd(fd); - rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ); - the_limits = &iop->pathinfo.mt_entry->pathconf_limits_and_options; switch ( name ) { diff --git a/cpukit/libcsupport/src/fsync.c b/cpukit/libcsupport/src/fsync.c index a5ed1e99e7..b77c77312c 100644 --- a/cpukit/libcsupport/src/fsync.c +++ b/cpukit/libcsupport/src/fsync.c @@ -22,22 +22,22 @@ int fsync( { rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + 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 ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the fsync(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); - if ( !iop->handlers->fsync ) set_errno_and_return_minus_one( ENOTSUP ); diff --git a/cpukit/libcsupport/src/ftruncate.c b/cpukit/libcsupport/src/ftruncate.c index 7fb2286531..5bcb2ea5d8 100644 --- a/cpukit/libcsupport/src/ftruncate.c +++ b/cpukit/libcsupport/src/ftruncate.c @@ -25,19 +25,20 @@ int ftruncate( rtems_libio_t *iop; rtems_filesystem_location_info_t loc; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + /* * If this is not a file system based entity, it is an error. */ - if ( rtems_file_descriptor_type( fd ) ) + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) set_errno_and_return_minus_one( EBADF ); /* * Now process the ftruncate() request. */ - iop = rtems_libio_iop( fd ); - /* * Make sure we are not working on a directory */ @@ -49,7 +50,6 @@ int ftruncate( if ( (*loc.ops->node_type)( &loc ) == RTEMS_FILESYSTEM_DIRECTORY ) set_errno_and_return_minus_one( EISDIR ); - rtems_libio_check_fd( fd ); rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); if ( !iop->handlers->ftruncate ) diff --git a/cpukit/libcsupport/src/ioctl.c b/cpukit/libcsupport/src/ioctl.c index 0aaf0379ae..9284c7f9dc 100644 --- a/cpukit/libcsupport/src/ioctl.c +++ b/cpukit/libcsupport/src/ioctl.c @@ -26,15 +26,19 @@ int ioctl( rtems_status_code rc; rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + /* * 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 ) ) { + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) { rtems_libio_ioctl_t fp; - fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].ioctl; + fp = rtems_libio_handlers[ + (iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].ioctl; if ( fp == NULL ) set_errno_and_return_minus_one( EBADF ); @@ -45,9 +49,6 @@ int ioctl( * Now process the ioctl(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - if ( !iop->handlers->ioctl ) set_errno_and_return_minus_one( ENOTSUP ); diff --git a/cpukit/libcsupport/src/libio.c b/cpukit/libcsupport/src/libio.c index e63a4626d4..88aea9b62f 100644 --- a/cpukit/libcsupport/src/libio.c +++ b/cpukit/libcsupport/src/libio.c @@ -3,9 +3,6 @@ * table of integer style file descriptors used by the low level * POSIX system calls like open(), read, fstat(), etc. * - * This provides the foundation for POSIX compliant IO system calls - * for RTEMS. - * * COPYRIGHT (c) 1989-1998. * On-Line Applications Research Corporation (OAR). * Copyright assigned to U.S. Government, 1994. @@ -18,17 +15,55 @@ */ #include "libio_.h" /* libio_.h pulls in rtems */ +#include +#include /* assoc.h not included by rtems.h */ + +#include /* O_RDONLY, et.al. */ +#include /* O_RDONLY, et.al. */ +#include +#include + +#if ! defined(O_NDELAY) +# if defined(solaris2) +# define O_NDELAY O_NONBLOCK +# elif defined(RTEMS_NEWLIB) +# define O_NDELAY _FNBIO +# endif +#endif + + +#include +#include /* strcmp */ +#include +#include /* calloc() */ + +#include "libio.h" /* libio.h not pulled in by rtems */ + +/* + * File descriptor Table Information + */ + +extern unsigned32 rtems_libio_number_iops; +rtems_id rtems_libio_semaphore; +rtems_libio_t *rtems_libio_iops; +rtems_libio_t *rtems_libio_last_iop; +rtems_libio_t *rtems_libio_iop_freelist; /* - * Global variables used to manage the File Descriptor Table. - * IOP = IO Pointer. + * External I/O Handlers Table + * + * Space for all possible handlers is preallocated + * to speed up dispatch to external handlers. */ -rtems_id rtems_libio_semaphore; -rtems_libio_t *rtems_libio_iops; -rtems_libio_t *rtems_libio_last_iop; rtems_libio_handler_t rtems_libio_handlers[15]; +/* + * Default mode for all files. + */ + +mode_t rtems_filesystem_umask; + /* * rtems_register_libio_handler * @@ -44,8 +79,7 @@ void rtems_register_libio_handler( const rtems_libio_handler_t *handler ) { - int handler_index = rtems_file_descriptor_type_index( handler_flag ); - + int handler_index = (handler_flag >> LIBIO_FLAGS_HANDLER_SHIFT) - 1; if ((handler_index < 0) || (handler_index >= 15)) rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER ); @@ -61,21 +95,22 @@ void rtems_register_libio_handler( void rtems_libio_init( void ) { - rtems_status_code rc; - - /* - * Allocate memory for the IOP Table - */ - - if ( rtems_libio_number_iops > 0 ) { - rtems_libio_iops = - (rtems_libio_t *) calloc(rtems_libio_number_iops, sizeof(rtems_libio_t)); - - if (rtems_libio_iops == NULL) - rtems_fatal_error_occurred( RTEMS_NO_MEMORY ); - - rtems_libio_last_iop = rtems_libio_iops + (rtems_libio_number_iops - 1); - } + rtems_status_code rc; + int i; + rtems_libio_t *iop; + + if (rtems_libio_number_iops > 0) + { + rtems_libio_iops = (rtems_libio_t *) calloc(rtems_libio_number_iops, + sizeof(rtems_libio_t)); + if (rtems_libio_iops == NULL) + rtems_fatal_error_occurred(RTEMS_NO_MEMORY); + + iop = rtems_libio_iop_freelist = rtems_libio_iops; + for (i = 0 ; i < (rtems_libio_number_iops - 1) ; i++, iop++) + iop->data1 = iop + 1; + iop->data1 = NULL; + } /* * Create the binary semaphore used to provide mutual exclusion @@ -157,24 +192,21 @@ rtems_libio_t *rtems_libio_allocate( void ) rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); - for (iop = rtems_libio_iops; iop <= rtems_libio_last_iop; iop++) - if ((iop->flags & LIBIO_FLAGS_OPEN) == 0) { - /* - * Got an IOP -- create a semaphore for it. - */ - - rc = rtems_semaphore_create( - RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops), - 1, - RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY, - RTEMS_NO_PRIORITY, - &iop->sem - ); - if ( rc != RTEMS_SUCCESSFUL ) - goto failed; - - iop->flags = LIBIO_FLAGS_OPEN; - goto done; + if (rtems_libio_iop_freelist) { + iop = rtems_libio_iop_freelist; + rc = rtems_semaphore_create( + RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops), + 1, + RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY, + RTEMS_NO_PRIORITY, + &iop->sem + ); + if (rc != RTEMS_SUCCESSFUL) + goto failed; + rtems_libio_iop_freelist = iop->data1; + iop->data1 = 0; + iop->flags = LIBIO_FLAGS_OPEN; + goto done; } failed: @@ -198,19 +230,20 @@ void rtems_libio_free( { rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); - if (iop->sem) - rtems_semaphore_delete(iop->sem); + if (iop->sem) + rtems_semaphore_delete(iop->sem); - (void) memset(iop, 0, sizeof(*iop)); + iop->data1 = rtems_libio_iop_freelist; + rtems_libio_iop_freelist = iop; - rtems_semaphore_release( rtems_libio_semaphore ); + rtems_semaphore_release(rtems_libio_semaphore); } /* * rtems_libio_is_open_files_in_fs * * This routine scans the entire file descriptor table to determine if the - * are any active file descriptors that refer to the atleast one node in the + * are any active file descriptors that refer to the at least one node in the * file system that we are trying to dismount. * * If there is at least one node in the file system referenced by the mount @@ -225,19 +258,19 @@ int rtems_libio_is_open_files_in_fs( int result = 0; rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); - + /* * Look for any active file descriptor entry. - */ - + */ + for ( iop=rtems_libio_iops ; iop <= rtems_libio_last_iop ; iop++ ) { - + if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) { - + /* * Check if this node is under the file system that we * are trying to dismount. - */ + */ if ( iop->pathinfo.mt_entry == fs_mt_entry ) { result = 1; @@ -247,7 +280,7 @@ int rtems_libio_is_open_files_in_fs( } rtems_semaphore_release( rtems_libio_semaphore ); - + return result; } @@ -256,7 +289,7 @@ int rtems_libio_is_open_files_in_fs( * * This routine scans the entire file descriptor table to determine if the * given file refers to an active file descriptor. - * + * * If the given file is open a 1 is returned, otherwise a 0 is returned. */ @@ -265,22 +298,22 @@ int rtems_libio_is_file_open( ) { rtems_libio_t *iop; - int result=0; + int result=0; rtems_semaphore_obtain( rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); /* * Look for any active file descriptor entry. */ - + for ( iop=rtems_libio_iops ; iop <= rtems_libio_last_iop ; iop++ ) { - + if ((iop->flags & LIBIO_FLAGS_OPEN) != 0) { - + /* * Check if this node is under the file system that we * are trying to dismount. - */ + */ if ( iop->pathinfo.node_access == node_access ) { result = 1; @@ -293,3 +326,5 @@ int rtems_libio_is_file_open( return result; } + + diff --git a/cpukit/libcsupport/src/lseek.c b/cpukit/libcsupport/src/lseek.c index 514f8cd912..cd8046356f 100644 --- a/cpukit/libcsupport/src/lseek.c +++ b/cpukit/libcsupport/src/lseek.c @@ -24,15 +24,19 @@ off_t lseek( { rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + /* * 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 ) ) { + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) { rtems_libio_lseek_t fp; - fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].lseek; + fp = rtems_libio_handlers[ + (iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].lseek; if ( fp == NULL ) set_errno_and_return_minus_one( EBADF ); @@ -43,9 +47,6 @@ off_t lseek( * Now process the lseek(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - switch ( whence ) { case SEEK_SET: iop->offset = offset; diff --git a/cpukit/libcsupport/src/read.c b/cpukit/libcsupport/src/read.c index 150fe675ab..1ed6a0bd00 100644 --- a/cpukit/libcsupport/src/read.c +++ b/cpukit/libcsupport/src/read.c @@ -26,15 +26,22 @@ int read( int rc; /* XXX change to a size_t when prototype is fixed */ rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_buffer( buffer ); + rtems_libio_check_count( count ); + 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 ( rtems_file_descriptor_type( fd ) ) { + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) { rtems_libio_read_t fp; - fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].read; + fp = rtems_libio_handlers[ + (iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].read; if ( fp == NULL ) set_errno_and_return_minus_one( EBADF ); @@ -45,12 +52,6 @@ int read( * Now process the read(). */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - rtems_libio_check_buffer( buffer ); - rtems_libio_check_count( count ); - rtems_libio_check_permissions( iop, LIBIO_FLAGS_READ ); - if ( !iop->handlers->read ) set_errno_and_return_minus_one( ENOTSUP ); diff --git a/cpukit/libcsupport/src/write.c b/cpukit/libcsupport/src/write.c index 7e0953bb90..3de21f0d0f 100644 --- a/cpukit/libcsupport/src/write.c +++ b/cpukit/libcsupport/src/write.c @@ -34,15 +34,22 @@ int write( /* XXX this should return a ssize_t */ rtems_status_code rc; rtems_libio_t *iop; + rtems_libio_check_fd( fd ); + iop = rtems_libio_iop( fd ); + rtems_libio_check_buffer( buffer ); + rtems_libio_check_count( count ); + 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 ( rtems_file_descriptor_type( fd ) ) { + if ( iop->flags & LIBIO_FLAGS_HANDLER_MASK ) { rtems_libio_write_t fp; - fp = rtems_libio_handlers[rtems_file_descriptor_type_index(fd)].write; + fp = rtems_libio_handlers[ + (iop->flags >> LIBIO_FLAGS_HANDLER_SHIFT) - 1].write; if ( fp == NULL ) set_errno_and_return_minus_one( EBADF ); @@ -53,12 +60,6 @@ int write( /* XXX this should return a ssize_t */ * Now process the write() request. */ - iop = rtems_libio_iop( fd ); - rtems_libio_check_fd( fd ); - rtems_libio_check_buffer( buffer ); - rtems_libio_check_count( count ); - rtems_libio_check_permissions( iop, LIBIO_FLAGS_WRITE ); - if ( !iop->handlers->write ) set_errno_and_return_minus_one( ENOTSUP ); diff --git a/cpukit/libnetworking/rtems/rtems_glue.c b/cpukit/libnetworking/rtems/rtems_glue.c index f2449831f5..28fb179c22 100644 --- a/cpukit/libnetworking/rtems/rtems_glue.c +++ b/cpukit/libnetworking/rtems/rtems_glue.c @@ -30,19 +30,6 @@ #include #include -/* - * Events used by networking routines. - * Everything will break if the application - * tries to use these events or if the `sleep' - * events are equal to any of the NETISR * events. - */ -#define SBWAIT_EVENT RTEMS_EVENT_24 -#define SOSLEEP_EVENT RTEMS_EVENT_25 -#define NETISR_IP_EVENT (1 << NETISR_IP) -#define NETISR_ARP_EVENT (1 << NETISR_ARP) -#define NETISR_EVENTS (NETISR_IP_EVENT|NETISR_ARP_EVENT) - - /* * Memory allocation */ @@ -246,7 +233,7 @@ rtems_bsdnet_initialize (void) /* * Register as an external I/O handler */ - rtems_register_libio_handler (RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET, + rtems_register_libio_handler (LIBIO_FLAGS_HANDLER_SOCK, &rtems_bsdnet_io_handler); /* @@ -305,16 +292,9 @@ sbwait(sb) /* * Set this task as the target of the wakeup operation. */ - if (sb->sb_sel.si_pid) - rtems_panic ("Another task is already sleeping on that socket buffer"); rtems_task_ident (RTEMS_SELF, 0, &tid); sb->sb_sel.si_pid = tid; - /* - * Mark the socket buffer as waiting. - */ - sb->sb_flags |= SB_WAIT; - /* * Release the network semaphore. */ @@ -330,12 +310,6 @@ sbwait(sb) */ rtems_bsdnet_semaphore_obtain (); - /* - * Relinquish ownership of the socket buffer - */ - sb->sb_flags &= ~SB_WAIT; - sb->sb_sel.si_pid = 0; - /* * Return the status of the wait. */ @@ -355,9 +329,11 @@ sowakeup(so, sb) register struct socket *so; register struct sockbuf *sb; { - if (sb->sb_flags & SB_WAIT) { - sb->sb_flags &= ~SB_WAIT; - rtems_event_send (sb->sb_sel.si_pid, SBWAIT_EVENT); + rtems_id tid; + + if ((tid = sb->sb_sel.si_pid) != 0) { + sb->sb_sel.si_pid = 0; + rtems_event_send (tid, SBWAIT_EVENT); } } diff --git a/cpukit/libnetworking/rtems/rtems_syscall.c b/cpukit/libnetworking/rtems/rtems_syscall.c index 93ecd47c6f..63d34bd817 100644 --- a/cpukit/libnetworking/rtems/rtems_syscall.c +++ b/cpukit/libnetworking/rtems/rtems_syscall.c @@ -25,77 +25,6 @@ #include #include -/* - ********************************************************************* - * Map RTEMS file descriptor to BSD socket * - ********************************************************************* - */ -struct fdsock { - int indexFreeNext; - struct socket *sock; -}; -static struct fdsock *fdsock; -static int fdsockCount; -static int indexFreeHead = -1; - -/* - * Convert an RTEMS file descriptor to a BSD socket pointer. - */ -static struct socket * -fdToSocket (int fd) -{ - int i; - struct socket *s; - - if ((fd < 0) - || (rtems_file_descriptor_type(fd) != RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET) - || ((i = rtems_file_descriptor_base(fd)) >= fdsockCount) - || ((s = fdsock[i].sock) == NULL)) { - errno = EBADF; - return NULL; - } - return s; -} - -/* - * Enlarge the size of the file-descritor/socket pointer map. - */ -static int -enlargeFdMap (void) -{ - struct fdsock *nfdsock; - int i; - - nfdsock = realloc (fdsock, sizeof *fdsock * (fdsockCount + 20)); - if (nfdsock == NULL) { - errno = ENFILE; - return 0; - } - fdsock = nfdsock; - for (i = fdsockCount, fdsockCount += 20 ; i < fdsockCount ; i++) { - fdsock[i].sock = NULL; - fdsock[i].indexFreeNext = indexFreeHead; - indexFreeHead = i; - } - return 1; -} - -/* - * Create a file descriptor for a new socket - */ -static int -makeFd (struct socket *s) -{ - int i; - - if ((indexFreeHead < 0) && !enlargeFdMap ()) - return -1; - i = indexFreeHead; - indexFreeHead = fdsock[i].indexFreeNext; - fdsock[i].sock = s; - return rtems_make_file_descriptor(i,RTEMS_FILE_DESCRIPTOR_TYPE_SOCKET); -} - /* * Package system call argument into mbuf. */ @@ -128,14 +57,14 @@ sockargstombuf (struct mbuf **mp, const void *buf, int buflen, int type) int socket (int domain, int type, int protocol) { - int fd = -1; + int fd; int error; struct socket *so; rtems_bsdnet_semaphore_obtain (); error = socreate(domain, &so, type, protocol, NULL); if (error == 0) { - fd = makeFd (so); + fd = rtems_bsdnet_makeFdForSocket (so); if (fd < 0) soclose (so); } @@ -156,7 +85,7 @@ bind (int s, struct sockaddr *name, int namelen) struct mbuf *nam; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) != NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) { error = sockargstombuf (&nam, name, namelen, MT_SONAME); if (error == 0) { error = sobind (so, nam); @@ -183,7 +112,7 @@ connect (int s, struct sockaddr *name, int namelen) struct mbuf *nam; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -233,7 +162,7 @@ listen (int s, int backlog) struct socket *so; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) != NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) { error = solisten (so, backlog); if (error == 0) ret = 0; @@ -252,7 +181,7 @@ accept (int s, struct sockaddr *name, int *namelen) struct mbuf *nam; rtems_bsdnet_semaphore_obtain (); - if ((head = fdToSocket (s)) == NULL) { + if ((head = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -284,7 +213,7 @@ accept (int s, struct sockaddr *name, int *namelen) TAILQ_REMOVE(&head->so_comp, so, so_list); head->so_qlen--; - fd = makeFd (so); + fd = rtems_bsdnet_makeFdForSocket (so); if (fd < 0) { TAILQ_INSERT_HEAD(&head->so_comp, so, so_list); head->so_qlen++; @@ -325,7 +254,7 @@ sendmsg (int s, const struct msghdr *mp, int flags) int len; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -428,7 +357,7 @@ recvmsg (int s, struct msghdr *mp, int flags) int len; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -547,7 +476,7 @@ setsockopt (int s, int level, int name, const void *val, int len) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -584,7 +513,7 @@ getsockopt (int s, int level, int name, void *aval, int *avalsize) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -626,7 +555,7 @@ getpeersockname (int s, struct sockaddr *name, int *namelen, int pflag) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (s)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } @@ -676,16 +605,12 @@ rtems_bsdnet_close (int fd) { struct socket *so; int error; - int i; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (fd)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } - i = rtems_file_descriptor_base(fd); - fdsock[i].indexFreeNext = indexFreeHead;; - indexFreeHead = i; error = soclose (so); rtems_bsdnet_semaphore_release (); if (error) { @@ -737,7 +662,7 @@ rtems_bsdnet_ioctl (int fd, unsigned32 command, void *buffer) int error; rtems_bsdnet_semaphore_obtain (); - if ((so = fdToSocket (fd)) == NULL) { + if ((so = rtems_bsdnet_fdToSocket (fd)) == NULL) { rtems_bsdnet_semaphore_release (); return -1; } -- cgit v1.2.3