From 94b3ee1366fddb9aca95f2f1ec61d633deb66510 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 21 Jan 1999 22:25:43 +0000 Subject: Made to compile after hacking tftp driver into beginnings of a mini-filesystem. --- c/src/exec/libnetworking/lib/tftpDriver.c | 143 +++++++++++++---- c/src/exec/libnetworking/libc/res_config.h | 4 +- .../libnetworking/rtems/rtems_bsdnet_internal.h | 16 +- c/src/exec/libnetworking/rtems/rtems_select.c | 171 +++++++++++++++++++++ c/src/exec/libnetworking/rtems/sghostname.c | 4 +- 5 files changed, 299 insertions(+), 39 deletions(-) create mode 100644 c/src/exec/libnetworking/rtems/rtems_select.c (limited to 'c/src/exec/libnetworking') diff --git a/c/src/exec/libnetworking/lib/tftpDriver.c b/c/src/exec/libnetworking/lib/tftpDriver.c index e7f99998e1..e9564110f5 100644 --- a/c/src/exec/libnetworking/lib/tftpDriver.c +++ b/c/src/exec/libnetworking/lib/tftpDriver.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include @@ -25,6 +26,12 @@ #include #include +#ifndef set_errno_and_return_minus_one +#define set_errno_and_return_minus_one( _error ) \ + do { errno = (_error); return -1; } while(0) +#endif + + /* * Range of UDP ports to try */ @@ -136,6 +143,50 @@ static rtems_id tftp_mutex; static int nStreams; static struct tftpStream ** volatile tftpStreams; +typedef struct { + rtems_id tftp_mutex; + int nStreams; + struct tftpStream ** volatile tftpStreams; + rtems_filesystem_mount_table_entry_t *mt_entry; +} tftp_fs_info; + +int rtems_tftp_mount_me( + rtems_filesystem_mount_table_entry_t *temp_mt_entry +) +{ + tftp_fs_info *fs_info; + rtems_status_code sc; + + /* + * Allocate stuff for this file system. + */ + + fs_info = calloc( 1, sizeof( tftp_fs_info )); + if ( !fs_info ) + set_errno_and_return_minus_one( ENOMEM ); + + temp_mt_entry->fs_info = fs_info; + temp_mt_entry->mt_fs_root.node_access = fs_info; + + + sc = rtems_semaphore_create ( + rtems_build_name('T', 'F', 'T', 'P'), + 1, + RTEMS_FIFO | + RTEMS_BINARY_SEMAPHORE | + RTEMS_NO_INHERIT_PRIORITY | + RTEMS_NO_PRIORITY_CEILING | + RTEMS_LOCAL, + 0, + &fs_info->tftp_mutex + ); + + if (sc != RTEMS_SUCCESSFUL) + set_errno_and_return_minus_one( ENOMEM ); /* ??? */ + + return 0; +} + /* * Initialize the TFTP driver */ @@ -147,19 +198,7 @@ rtems_device_driver rtems_tftp_initialize( void *pargp ) { - rtems_status_code sc; - sc = rtems_semaphore_create (rtems_build_name('T', 'F', 'T', 'P'), - 1, - RTEMS_FIFO | - RTEMS_BINARY_SEMAPHORE | - RTEMS_NO_INHERIT_PRIORITY | - RTEMS_NO_PRIORITY_CEILING | - RTEMS_LOCAL, - 0, - &tftp_mutex); - if (sc != RTEMS_SUCCESSFUL) - return sc; /* XXX change to a mount */ rtems_io_register_name (TFTP_PATHNAME_PREFIX, major, minor); return RTEMS_SUCCESSFUL; @@ -293,39 +332,44 @@ releaseStream (int s) rtems_semaphore_release (tftp_mutex); } +int rtems_tftp_evaluate_for_make( + const char *path, /* IN */ + rtems_filesystem_location_info_t *pathloc, /* IN/OUT */ + const char **name /* OUT */ +) +{ + set_errno_and_return_minus_one( EIO ); +} /* - * Open a TFTP stream + * XXX - Fix return values. */ -rtems_device_driver rtems_tftp_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *pargp + +int TFTP_eval_path( + const char *pathname, /* IN */ + int flags, /* IN */ + rtems_filesystem_location_info_t *pathloc /* IN/OUT */ ) { - rtems_libio_open_close_args_t *ap = pargp; - struct tftpStream *tp; - int retryCount; rtems_unsigned32 farAddress; - int s; int len; - char *cp1, *cp2; - char *remoteFilename; - rtems_interval now; - rtems_status_code sc; + const char *remoteFilename; -/* XXX change to eval_path/open */ - /* - * Read-only for now - */ - if (ap->flags & LIBIO_FLAGS_WRITE) - return RTEMS_NOT_IMPLEMENTED; + tftp_fs_info *fs_info; + const char *cp1, *cp2; + + fs_info = pathloc->node_access; /* * Pick apart the name into a host:pathname pair */ - if (strlen (ap->iop->pathname) <= strlen (TFTP_PATHNAME_PREFIX)) - return RTEMS_INVALID_NAME; - cp2 = ap->iop->pathname + strlen (TFTP_PATHNAME_PREFIX); + /* + * XXX - I think this is handled by the caller of + * the evaluate routine. ? Am I starting at the right + * place? + */ + + cp2 = pathname+1; + if (*cp2 == '/') { farAddress = rtems_bsdnet_bootp_server_address.s_addr; } @@ -355,6 +399,37 @@ rtems_device_driver rtems_tftp_open( if (strlen (remoteFilename) > (TFTP_BUFSIZE - 10)) return RTEMS_INVALID_NAME; + return 0; +} + +/* + * Open a TFTP stream + */ +rtems_device_driver rtems_tftp_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +) +{ + rtems_libio_open_close_args_t *ap = pargp; + struct tftpStream *tp; + int retryCount; + rtems_unsigned32 farAddress = 0; /* XXX - node parameter */ + int s; + int len; + char *cp1, *cp2; + char *remoteFilename = NULL; /* XXX - node parameter */ + rtems_interval now; + rtems_status_code sc; + + /* + * Read-only for now + */ + /* XXX - Move to the open routine */ + if (ap->flags & LIBIO_FLAGS_WRITE) + return RTEMS_NOT_IMPLEMENTED; + + /* * Find a free stream */ diff --git a/c/src/exec/libnetworking/libc/res_config.h b/c/src/exec/libnetworking/libc/res_config.h index 57ec414226..fbd1d694f7 100644 --- a/c/src/exec/libnetworking/libc/res_config.h +++ b/c/src/exec/libnetworking/libc/res_config.h @@ -14,7 +14,7 @@ #if defined(__rtems__) u_int16_t _getshort(const u_char *src); u_int32_t _getlong(const u_char *src); -int gethostname (char *name, int namelen); -int sethostname (char *name, int namelen); +int gethostname (char *name, size_t namelen); +int sethostname (char *name, size_t namelen); int issetugid (void); #endif diff --git a/c/src/exec/libnetworking/rtems/rtems_bsdnet_internal.h b/c/src/exec/libnetworking/rtems/rtems_bsdnet_internal.h index 453fb23c66..5d355f4a36 100644 --- a/c/src/exec/libnetworking/rtems/rtems_bsdnet_internal.h +++ b/c/src/exec/libnetworking/rtems/rtems_bsdnet_internal.h @@ -166,7 +166,7 @@ extern int rtems_bsdnet_nameserver_count; /* * Some extra prototypes */ -int sethostname (char *name, int namelen); +int sethostname (char *name, size_t namelen); void domaininit (void *); void ifinit (void *); void ipintr (void); @@ -174,5 +174,19 @@ void arpintr (void); void bootpc_init(void); int socket (int, int, int); int ioctl (int, unsigned long, ...); +struct socket *rtems_bsdnet_fdToSocket (int fd); +int rtems_bsdnet_makeFdForSocket (struct socket *); + +/* + * 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) #endif /* _RTEMS_BSDNET_INTERNAL_H_ */ diff --git a/c/src/exec/libnetworking/rtems/rtems_select.c b/c/src/exec/libnetworking/rtems/rtems_select.c new file mode 100644 index 0000000000..2487edf9fc --- /dev/null +++ b/c/src/exec/libnetworking/rtems/rtems_select.c @@ -0,0 +1,171 @@ +/* + * $Id$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* + ********************************************************************* + * RTEMS implementation of select() system call * + ********************************************************************* + */ + +/* + * This implementation is quite restricted: + * Works on sockets only -- no support for other devices! + * A given socket can be in a read-select or a read/recv* by only + * one task at a time. + * A given socket can be in a write-select or a write/send* by only + * one task at a time. + * + * NOTE - select() is a very expensive system call. It should be avoided + * if at all possible. In many cases, rewriting the application + * to use multiple tasks (one per socket) is a better solution. + */ + +static __inline int imin(int a, int b) { return (a < b ? a : b); } + +static int +socket_select (struct socket *so, int which, rtems_id tid) +{ + switch (which) { + + case FREAD: + if (soreadable(so)) + return (1); + so->so_rcv.sb_sel.si_pid = tid; + break; + + case FWRITE: + if (sowriteable(so)) + return (1); + so->so_snd.sb_sel.si_pid = tid; + break; + + case 0: + if (so->so_oobmark || (so->so_state & SS_RCVATMARK)) + return (1); + so->so_rcv.sb_sel.si_pid = tid; + break; + } + return (0); +} + +static int +selscan (rtems_id tid, fd_mask **ibits, fd_mask **obits, int nfd, int *retval) +{ + struct socket *so; + int msk, i, fd; + fd_mask bits, bit; + int n = 0; + static int flag[3] = { FREAD, FWRITE, 0 }; + + for (msk = 0; msk < 3; msk++) { + if (ibits[msk] == NULL) + continue; + for (i = 0; i < nfd; i += NFDBITS) { + bits = ibits[msk][i/NFDBITS]; + for (fd = i, bit = 1 ; bits && (fd < nfd) ; fd++, bit <<= 1) { + if ((bits & bit) == 0) + continue; + bits &= ~bit; + so = rtems_bsdnet_fdToSocket (fd); + if (so == NULL) + return (EBADF); + if (socket_select (so, flag[msk], tid)) { + obits[msk][fd/NFDBITS] |= + (1 << (fd % NFDBITS)); + n++; + } + } + } + } + *retval = n; + return (0); +} + +int +select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *tv) +{ + fd_mask *ibits[3], *obits[3]; + fd_set ob[3]; + int error, timo; + int retval; + rtems_id tid; + rtems_interval then, now; + rtems_event_set events; + + if (nfds < 0) + return (EINVAL); + if (tv) { + timo = tv->tv_sec * hz + tv->tv_usec / tick; + if (timo == 0) + timo = 1; + rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then); + } + else { + timo = 0; + } + +#define getbits(name,i) if (name) { \ + ibits[i] = &name->fds_bits[0]; \ + obits[i] = &ob[i].fds_bits[0]; \ + FD_ZERO(&ob[i]); \ + } \ + else ibits[i] = NULL + getbits (readfds, 0); + getbits (writefds, 1); + getbits (exceptfds, 2); +#undef getbits + + rtems_task_ident (RTEMS_SELF, 0, &tid); + rtems_event_receive (SBWAIT_EVENT, RTEMS_EVENT_ANY | RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT, &events); + for (;;) { + rtems_bsdnet_semaphore_obtain (); + error = selscan(tid, ibits, obits, nfds, &retval); + rtems_bsdnet_semaphore_release (); + if (error || retval) + break; + if (timo) { + rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now); + timo -= now - then; + if (timo <= 0) + break; + then = now; + } + rtems_event_receive (SBWAIT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, timo, &events); + } + +#define putbits(name,i) if (name) *name = ob[i] + putbits (readfds, 0); + putbits (writefds, 1); + putbits (exceptfds, 2); +#undef putbits + if (error) { + errno = error; + retval = -1; + } + return (retval); +} diff --git a/c/src/exec/libnetworking/rtems/sghostname.c b/c/src/exec/libnetworking/rtems/sghostname.c index 36894caa86..307f045fbd 100644 --- a/c/src/exec/libnetworking/rtems/sghostname.c +++ b/c/src/exec/libnetworking/rtems/sghostname.c @@ -15,7 +15,7 @@ static char *rtems_hostname; int -gethostname (char *name, int namelen) +gethostname (char *name, size_t namelen) { char *cp = rtems_hostname; @@ -26,7 +26,7 @@ gethostname (char *name, int namelen) } int -sethostname (char *name, int namelen) +sethostname (char *name, size_t namelen) { char *old, *new; -- cgit v1.2.3