summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libnetworking/rtems/rtems_syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libnetworking/rtems/rtems_syscall.c')
-rw-r--r--c/src/lib/libnetworking/rtems/rtems_syscall.c760
1 files changed, 0 insertions, 760 deletions
diff --git a/c/src/lib/libnetworking/rtems/rtems_syscall.c b/c/src/lib/libnetworking/rtems/rtems_syscall.c
deleted file mode 100644
index 72fb43688e..0000000000
--- a/c/src/lib/libnetworking/rtems/rtems_syscall.c
+++ /dev/null
@@ -1,760 +0,0 @@
-/*
- * $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/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/fcntl.h>
-#include <sys/filio.h>
-
-#include <net/if.h>
-#include <net/route.h>
-
-/*
- * Hooks to RTEMS I/O system
- */
-static const rtems_filesystem_file_handlers_r socket_handlers;
-int rtems_bsdnet_makeFdForSocket(void *so, const rtems_filesystem_file_handlers_r *h);
-struct socket *rtems_bsdnet_fdToSocket(int fd);
-
-/*
- * Package system call argument into mbuf.
- */
-static int
-sockargstombuf (struct mbuf **mp, const void *buf, int buflen, int type)
-{
- struct mbuf *m;
-
- if ((u_int)buflen > MLEN)
- return (EINVAL);
- m = m_get(M_WAIT, type);
- if (m == NULL)
- return (ENOBUFS);
- m->m_len = buflen;
- memcpy (mtod(m, caddr_t), buf, buflen);
- *mp = m;
- if (type == MT_SONAME) {
- struct sockaddr *sa;
- sa = mtod(m, struct sockaddr *);
- sa->sa_len = buflen;
- }
- return 0;
-}
-
-/*
- *********************************************************************
- * BSD-style entry points *
- *********************************************************************
- */
-int
-socket (int domain, int type, int protocol)
-{
- int fd;
- int error;
- struct socket *so;
-
- rtems_bsdnet_semaphore_obtain ();
- error = socreate(domain, &so, type, protocol, NULL);
- if (error == 0) {
- fd = rtems_bsdnet_makeFdForSocket (so, &socket_handlers);
- if (fd < 0)
- soclose (so);
- }
- else {
- errno = error;
- fd = -1;
- }
- rtems_bsdnet_semaphore_release ();
- return fd;
-}
-
-int
-bind (int s, struct sockaddr *name, int namelen)
-{
- int error;
- int ret = -1;
- struct socket *so;
- struct mbuf *nam;
-
- rtems_bsdnet_semaphore_obtain ();
- if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) {
- error = sockargstombuf (&nam, name, namelen, MT_SONAME);
- if (error == 0) {
- error = sobind (so, nam);
- if (error == 0)
- ret = 0;
- else
- errno = error;
- m_freem (nam);
- }
- else {
- errno = error;
- }
- }
- rtems_bsdnet_semaphore_release ();
- return ret;
-}
-
-int
-connect (int s, struct sockaddr *name, int namelen)
-{
- int error;
- int ret = -1;
- struct socket *so;
- struct mbuf *nam;
-
- rtems_bsdnet_semaphore_obtain ();
- if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
- errno = EALREADY;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- error = sockargstombuf (&nam, name, namelen, MT_SONAME);
- if (error) {
- errno = error;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- error = soconnect (so, nam);
- if (error) {
- errno = error;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
- m_freem(nam);
- errno = EINPROGRESS;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
- so->so_error = soconnsleep (so);
- }
- if (error == 0) {
- error = so->so_error;
- so->so_error = 0;
- }
- so->so_state &= ~SS_ISCONNECTING;
- m_freem (nam);
- if (error == 0)
- ret = 0;
- rtems_bsdnet_semaphore_release ();
- return ret;
-}
-
-int
-listen (int s, int backlog)
-{
- int error;
- int ret = -1;
- struct socket *so;
-
- rtems_bsdnet_semaphore_obtain ();
- if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) {
- error = solisten (so, backlog);
- if (error == 0)
- ret = 0;
- else
- errno = error;
- }
- rtems_bsdnet_semaphore_release ();
- return ret;
-}
-
-int
-accept (int s, struct sockaddr *name, int *namelen)
-{
- int fd;
- struct socket *head, *so;
- struct mbuf *nam;
-
- rtems_bsdnet_semaphore_obtain ();
- if ((head = rtems_bsdnet_fdToSocket (s)) == NULL) {
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- if ((head->so_options & SO_ACCEPTCONN) == 0) {
- errno = EINVAL;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- if ((head->so_state & SS_NBIO) && head->so_comp.tqh_first == NULL) {
- errno = EWOULDBLOCK;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- while (head->so_comp.tqh_first == NULL && head->so_error == 0) {
- if (head->so_state & SS_CANTRCVMORE) {
- head->so_error = ECONNABORTED;
- break;
- }
- head->so_error = soconnsleep (head);
- }
- if (head->so_error) {
- errno = head->so_error;
- head->so_error = 0;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
-
- so = head->so_comp.tqh_first;
- TAILQ_REMOVE(&head->so_comp, so, so_list);
- head->so_qlen--;
-
- fd = rtems_bsdnet_makeFdForSocket (so, &socket_handlers);
- if (fd < 0) {
- TAILQ_INSERT_HEAD(&head->so_comp, so, so_list);
- head->so_qlen++;
- soconnwakeup (head);
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- so->so_state &= ~SS_COMP;
- so->so_head = NULL;
-
- nam = m_get(M_WAIT, MT_SONAME);
- (void) soaccept(so, nam);
- if (name) {
- /* check length before it is destroyed */
- if (*namelen > nam->m_len)
- *namelen = nam->m_len;
- memcpy (name, mtod(nam, caddr_t), *namelen);
- }
- m_freem(nam);
- rtems_bsdnet_semaphore_release ();
- return (fd);
-
-}
-
-/*
- * Shutdown routine
- */
-
-int
-shutdown (int s, int how)
-{
- struct socket *so;
- int error;
-
- rtems_bsdnet_semaphore_obtain ();
- if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- error = soshutdown(so, how);
- rtems_bsdnet_semaphore_release ();
- if (error) {
- errno = error;
- return -1;
- }
- return 0;
-}
-
-/*
- * All `transmit' operations end up calling this routine.
- */
-ssize_t
-sendmsg (int s, const struct msghdr *mp, int flags)
-{
- int ret = -1;
- int error;
- struct uio auio;
- struct iovec *iov;
- struct socket *so;
- struct mbuf *to, *control;
- int i;
- int len;
-
- rtems_bsdnet_semaphore_obtain ();
- if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- auio.uio_iov = mp->msg_iov;
- auio.uio_iovcnt = mp->msg_iovlen;
- auio.uio_segflg = UIO_USERSPACE;
- auio.uio_rw = UIO_WRITE;
- auio.uio_offset = 0;
- auio.uio_resid = 0;
- iov = mp->msg_iov;
- for (i = 0; i < mp->msg_iovlen; i++, iov++) {
- if ((auio.uio_resid += iov->iov_len) < 0) {
- errno = EINVAL;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- }
- if (mp->msg_name) {
- error = sockargstombuf (&to, mp->msg_name, mp->msg_namelen, MT_SONAME);
- if (error) {
- errno = error;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- }
- else {
- to = NULL;
- }
- if (mp->msg_control) {
- if (mp->msg_controllen < sizeof (struct cmsghdr)) {
- errno = EINVAL;
- if (to)
- m_freem(to);
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- sockargstombuf (&control, mp->msg_control, mp->msg_controllen, MT_CONTROL);
- }
- else {
- control = NULL;
- }
- len = auio.uio_resid;
- error = sosend (so, to, &auio, (struct mbuf *)0, control, flags);
- if (error) {
- if (auio.uio_resid != len && (error == EINTR || error == EWOULDBLOCK))
- error = 0;
- }
- if (error)
- errno = error;
- else
- ret = len - auio.uio_resid;
- if (to)
- m_freem(to);
- rtems_bsdnet_semaphore_release ();
- return (ret);
-}
-
-/*
- * Send a message to a host
- */
-ssize_t
-sendto (int s, const void *buf, size_t buflen, int flags, const struct sockaddr *to, int tolen)
-{
- struct msghdr msg;
- struct iovec iov;
-
- iov.iov_base = (void *)buf;
- iov.iov_len = buflen;
- msg.msg_name = (caddr_t)to;
- msg.msg_namelen = tolen;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- return sendmsg (s, &msg, flags);
-}
-
-/*
- * Send a message to a connected host
- */
-ssize_t
-send (int s, const void *buf, size_t buflen, int flags)
-{
- return sendto (s, buf, buflen, flags, NULL, 0);
-}
-
-/*
- * All `receive' operations end up calling this routine.
- */
-ssize_t
-recvmsg (int s, struct msghdr *mp, int flags)
-{
- int ret = -1;
- int error;
- struct uio auio;
- struct iovec *iov;
- struct socket *so;
- struct mbuf *from = NULL, *control = NULL;
- int i;
- int len;
-
- rtems_bsdnet_semaphore_obtain ();
- if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- auio.uio_iov = mp->msg_iov;
- auio.uio_iovcnt = mp->msg_iovlen;
- auio.uio_segflg = UIO_USERSPACE;
- auio.uio_rw = UIO_READ;
- auio.uio_offset = 0;
- auio.uio_resid = 0;
- iov = mp->msg_iov;
- for (i = 0; i < mp->msg_iovlen; i++, iov++) {
- if ((auio.uio_resid += iov->iov_len) < 0) {
- errno = EINVAL;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- }
- len = auio.uio_resid;
- mp->msg_flags = flags;
- error = soreceive (so, &from, &auio, (struct mbuf **)NULL,
- mp->msg_control ? &control : (struct mbuf **)NULL,
- &mp->msg_flags);
- if (error) {
- if (auio.uio_resid != len && (error == EINTR || error == EWOULDBLOCK))
- error = 0;
- }
- if (error) {
- errno = error;
- }
- else {
- ret = len - auio.uio_resid;
- if (mp->msg_name) {
- len = mp->msg_namelen;
- if ((len <= 0) || (from == NULL)) {
- len = 0;
- }
- else {
- if (len > from->m_len)
- len = from->m_len;
- memcpy (mp->msg_name, mtod(from, caddr_t), len);
- }
- mp->msg_namelen = len;
- }
- if (mp->msg_control) {
- struct mbuf *m;
- caddr_t ctlbuf;
-
- len = mp->msg_controllen;
- m = control;
- mp->msg_controllen = 0;
- ctlbuf = (caddr_t) mp->msg_control;
-
- while (m && (len > 0)) {
- unsigned int tocopy;
-
- if (len >= m->m_len)
- tocopy = m->m_len;
- else {
- mp->msg_flags |= MSG_CTRUNC;
- tocopy = len;
- }
- memcpy(ctlbuf, mtod(m, caddr_t), tocopy);
- ctlbuf += tocopy;
- len -= tocopy;
- m = m->m_next;
- }
- mp->msg_controllen = ctlbuf - mp->msg_control;
- }
- }
- if (from)
- m_freem (from);
- if (control)
- m_freem (control);
- rtems_bsdnet_semaphore_release ();
- return (ret);
-}
-
-/*
- * Receive a message from a host
- */
-ssize_t
-recvfrom (int s, void *buf, size_t buflen, int flags, const struct sockaddr *from, int *fromlen)
-{
- struct msghdr msg;
- struct iovec iov;
- int ret;
-
- iov.iov_base = buf;
- iov.iov_len = buflen;
- msg.msg_name = (caddr_t)from;
- if (fromlen)
- msg.msg_namelen = *fromlen;
- else
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- ret = recvmsg (s, &msg, flags);
- if ((from != NULL) && (fromlen != NULL) && (ret >= 0))
- *fromlen = msg.msg_namelen;
- return ret;
-}
-
-/*
- * Receive a message from a connected host
- */
-ssize_t
-recv (int s, void *buf, size_t buflen, int flags)
-{
- return recvfrom (s, buf, buflen, flags, NULL, NULL);
-}
-
-int
-setsockopt (int s, int level, int name, const void *val, int len)
-{
- struct socket *so;
- struct mbuf *m = NULL;
- int error;
-
- rtems_bsdnet_semaphore_obtain ();
- if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- if (len > MLEN) {
- errno = EINVAL;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- if (val) {
- error = sockargstombuf (&m, val, len, MT_SOOPTS);
- if (error) {
- errno = error;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- }
- error = sosetopt(so, level, name, m);
- if (error) {
- errno = error;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- rtems_bsdnet_semaphore_release ();
- return 0;
-}
-
-int
-getsockopt (int s, int level, int name, void *aval, int *avalsize)
-{
- struct socket *so;
- struct mbuf *m = NULL, *m0;
- char *val = aval;
- int i, op, valsize;
- int error;
-
- rtems_bsdnet_semaphore_obtain ();
- if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- if (val)
- valsize = *avalsize;
- else
- valsize = 0;
- if (((error = sogetopt(so, level, name, &m)) == 0) && val && valsize && m) {
- op = 0;
- while (m && op < valsize) {
- i = valsize - op;
- if (i > m->m_len)
- i = m->m_len;
- memcpy (val, mtod(m, caddr_t), i);
- op += i;
- val += i;
- m0 = m;
- MFREE (m0, m);
- }
- *avalsize = op;
- }
- if (m != NULL)
- (void) m_free(m);
- if (error) {
- errno = error;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- rtems_bsdnet_semaphore_release ();
- return 0;
-}
-
-static int
-getpeersockname (int s, struct sockaddr *name, int *namelen, int pflag)
-{
- struct socket *so;
- struct mbuf *m;
- int len = *namelen;
- int error;
-
- rtems_bsdnet_semaphore_obtain ();
- if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- m = m_getclr(M_WAIT, MT_SONAME);
- if (m == NULL) {
- errno = ENOBUFS;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- if (pflag)
- error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, m);
- else
- error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, m);
- if (error) {
- errno = error;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- if (len > m->m_len) {
- len = m->m_len;
- *namelen = len;
- }
- memcpy (name, mtod(m, caddr_t), len);
- m_freem (m);
- rtems_bsdnet_semaphore_release ();
- return 0;
-}
-
-int
-getpeername (int s, struct sockaddr *name, int *namelen)
-{
- return getpeersockname (s, name, namelen, 1);
-}
-int
-getsockname (int s, struct sockaddr *name, int *namelen)
-{
- return getpeersockname (s, name, namelen, 0);
-}
-
-/*
- ************************************************************************
- * RTEMS I/O HANDLER ROUTINES *
- ************************************************************************
- */
-static int
-rtems_bsdnet_close (rtems_libio_t *iop)
-{
- struct socket *so;
- int error;
-
- rtems_bsdnet_semaphore_obtain ();
- if ((so = iop->data1) == NULL) {
- errno = EBADF;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- error = soclose (so);
- rtems_bsdnet_semaphore_release ();
- if (error) {
- errno = error;
- return -1;
- }
- return 0;
-}
-
-static int
-rtems_bsdnet_read (rtems_libio_t *iop, void *buffer, unsigned32 count)
-{
- return recv (iop->data0, buffer, count, 0);
-}
-
-static int
-rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, unsigned32 count)
-{
- return send (iop->data0, buffer, count, 0);
-}
-
-static int
-so_ioctl (rtems_libio_t *iop, struct socket *so, unsigned32 command, void *buffer)
-{
- switch (command) {
- case FIONBIO:
- if (*(int *)buffer) {
- iop->flags |= O_NONBLOCK;
- so->so_state |= SS_NBIO;
- }
- else {
- iop->flags &= ~O_NONBLOCK;
- so->so_state &= ~SS_NBIO;
- }
- return 0;
-
- case FIONREAD:
- *(int *)buffer = so->so_rcv.sb_cc;
- return 0;
- }
-
- if (IOCGROUP(command) == 'i')
- return ifioctl (so, command, buffer, NULL);
- if (IOCGROUP(command) == 'r')
- return rtioctl (command, buffer, NULL);
- return (*so->so_proto->pr_usrreqs->pru_control)(so, command, buffer, 0);
-}
-
-static int
-rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
-{
- struct socket *so;
- int error;
-
- rtems_bsdnet_semaphore_obtain ();
- if ((so = iop->data1) == NULL) {
- errno = EBADF;
- rtems_bsdnet_semaphore_release ();
- return -1;
- }
- error = so_ioctl (iop, so, command, buffer);
- rtems_bsdnet_semaphore_release ();
- if (error) {
- errno = error;
- return -1;
- }
- return 0;
-}
-
-static int
-rtems_bsdnet_fcntl (int cmd, rtems_libio_t *iop)
-{
- struct socket *so;
-
- if (cmd == F_SETFL) {
- rtems_bsdnet_semaphore_obtain ();
- if ((so = iop->data1) == NULL) {
- rtems_bsdnet_semaphore_release ();
- return EBADF;
- }
- if (iop->flags & O_NONBLOCK)
- so->so_state |= SS_NBIO;
- else
- so->so_state &= ~SS_NBIO;
- rtems_bsdnet_semaphore_release ();
- }
- return 0;
-}
-
-static int
-rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
-{
- sp->st_mode = S_IFSOCK;
- return 0;
-}
-
-static const rtems_filesystem_file_handlers_r socket_handlers = {
- NULL, /* open */
- rtems_bsdnet_close, /* close */
- rtems_bsdnet_read, /* read */
- rtems_bsdnet_write, /* write */
- rtems_bsdnet_ioctl, /* ioctl */
- NULL, /* lseek */
- rtems_bsdnet_fstat, /* fstat */
- NULL, /* fchmod */
- NULL, /* ftruncate */
- NULL, /* fpathconf */
- NULL, /* fsync */
- NULL, /* fdatasync */
- rtems_bsdnet_fcntl, /* fcntl */
-};