summaryrefslogtreecommitdiffstats
path: root/c/src/exec
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/exec')
-rw-r--r--c/src/exec/libnetworking/lib/tftpDriver.c143
-rw-r--r--c/src/exec/libnetworking/libc/res_config.h4
-rw-r--r--c/src/exec/libnetworking/rtems/rtems_bsdnet_internal.h16
-rw-r--r--c/src/exec/libnetworking/rtems/rtems_select.c171
-rw-r--r--c/src/exec/libnetworking/rtems/sghostname.c4
5 files changed, 299 insertions, 39 deletions
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 <stdio.h>
+#include <stdlib.h>
#include <errno.h>
#include <malloc.h>
#include <string.h>
@@ -25,6 +26,12 @@
#include <netinet/in.h>
#include <arpa/inet.h>
+#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 <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/error.h>
+#include <rtems/rtems_bsdnet.h>
+
+#include <sys/errno.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/protosw.h>
+#include <sys/proc.h>
+#include <sys/filio.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+/*
+ *********************************************************************
+ * 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;