⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtems_syscall.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  $Id: rtems_syscall.c,v 1.17.2.1 2003/05/29 19:09:45 joel Exp $ */#include <string.h>#include <stdarg.h>/* #include <stdlib.h> */#include <stdio.h>#include <errno.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 <sys/sysctl.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 intsockargstombuf (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                      * ********************************************************************* */intsocket (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;}intbind (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;}intconnect (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)		goto bad;	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) {		error = soconnsleep (so);		if (error)			break;	}	if (error == 0) {		error = so->so_error;		so->so_error = 0;	}    bad:	so->so_state &= ~SS_ISCONNECTING;	m_freem (nam);	if (error)		errno = error;	else		ret = 0;	rtems_bsdnet_semaphore_release ();	return ret;}intlisten (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;}intaccept (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 */intshutdown (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_tsendmsg (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_tsendto (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_tsend (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_trecvmsg (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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -