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

📄 uipc_syscalls.c

📁 很好的一个嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: uipc_syscalls.c,v 1.3 1998/06/17 00:49:49 chris Exp $ *//* * Copyright (c) 1982, 1986, 1989, 1990 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)uipc_syscalls.c	7.24 (Berkeley) 6/3/91 */#include "param.h"#include "filedesc.h"#include "proc.h"#include "file.h"#include "buf.h"#include "malloc.h"#include "mbuf.h"#include "protosw.h"#include "socket.h"#include "socketvar.h"#ifdef KTRACE#include "ktrace.h"#endif/* * System call interface to the socket abstraction. */extern const struct fileops socketops;SYSCALL(socket)(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	domain;		int	type;		int	protocol;	} *uap = v;	struct filedesc *fdp = p->p_fd;	struct socket *so;	struct file *fp;	int fd, error;	if (error = falloc(p, &fp, &fd))		return (error);	fp->f_flag = FREAD|FWRITE;	fp->f_type = DTYPE_SOCKET;	fp->f_ops = &socketops;	if (error = socreate(uap->domain, &so, uap->type, uap->protocol)) {		fdp->fd_ofiles[fd] = 0;		ffree(fp);	} else {		fp->f_data = (caddr_t)so;		*retval = fd;	}	return (error);}/* ARGSUSED */SYSCALL(bind)(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	s;		caddr_t	name;		int	namelen;	} *uap = v;	struct file *fp;	struct mbuf *nam;	int error;	if (error = getsock(p->p_fd, uap->s, &fp))		return (error);	if (error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME))		return (error);	error = sobind((struct socket *)fp->f_data, nam);	m_freem(nam);	return (error);}/* ARGSUSED */SYSCALL(listen)(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	s;		int	backlog;	} *uap = v;	struct file *fp;	int error;	if (error = getsock(p->p_fd, uap->s, &fp))		return (error);	return (solisten((struct socket *)fp->f_data, uap->backlog));}#ifdef COMPAT_43SYSCALL(accept)(p, uap, retval)	struct proc *p;	struct args {		int	s;		caddr_t	name;		int	*anamelen;		int	compat_43;	} *uap;	int *retval;{	uap->compat_43 = 0;	return (accept1(p, uap, retval));}SYSCALL(oaccept)(p, uap, retval)	struct proc *p;	struct args {		int	s;		caddr_t	name;		int	*anamelen;		int	compat_43;	} *uap;	int *retval;{	uap->compat_43 = 1;	return (accept1(p, uap, retval));}#else /* COMPAT_43 */#define	accept1	SYSCALL(accept)#endifaccept1(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	s;		caddr_t	name;		int	*anamelen;#ifdef COMPAT_43		int	compat_43;#endif	} *uap = v;	struct file *fp;	struct mbuf *nam;	int namelen, error, s;	register struct socket *so;	if (uap->name && (error = copyin((caddr_t)uap->anamelen,	    (caddr_t)&namelen, sizeof (namelen))))		return (error);	if (error = getsock(p->p_fd, uap->s, &fp))		return (error);	s = splnet();	so = (struct socket *)fp->f_data;	if ((so->so_options & SO_ACCEPTCONN) == 0) {		splx(s);		return (EINVAL);	}	if ((so->so_state & SS_NBIO) && so->so_qlen == 0) {		splx(s);		return (EWOULDBLOCK);	}	while (so->so_qlen == 0 && so->so_error == 0) {		if (so->so_state & SS_CANTRCVMORE) {			so->so_error = ECONNABORTED;			break;		}		if (error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,		    netcon, 0)) {			splx(s);			return (error);		}	}	if (so->so_error) {		error = so->so_error;		so->so_error = 0;		splx(s);		return (error);	}	if (error = falloc(p, &fp, retval)) {		splx(s);		return (error);	}	{ struct socket *aso = so->so_q;	  if (soqremque(aso, 1) == 0)		panic("accept");	  so = aso;	}	fp->f_type = DTYPE_SOCKET;	fp->f_flag = FREAD|FWRITE;	fp->f_ops = &socketops;	fp->f_data = (caddr_t)so;	nam = m_get(M_WAIT, MT_SONAME);	(void) soaccept(so, nam);	if (uap->name) {#ifdef COMPAT_43		if (uap->compat_43)			mtod(nam, struct osockaddr *)->sa_family =			    mtod(nam, struct sockaddr *)->sa_family;#endif		if (namelen > nam->m_len)			namelen = nam->m_len;		/* SHOULD COPY OUT A CHAIN HERE */		if ((error = copyout(mtod(nam, caddr_t), (caddr_t)uap->name,		    (u_int)namelen)) == 0)			error = copyout((caddr_t)&namelen,			    (caddr_t)uap->anamelen, sizeof (*uap->anamelen));	}	m_freem(nam);	splx(s);	return (error);}/* ARGSUSED */SYSCALL(connect)(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	s;		caddr_t	name;		int	namelen;	} *uap = v;	struct file *fp;	register struct socket *so;	struct mbuf *nam;	int error, s;	if (error = getsock(p->p_fd, uap->s, &fp))		return (error);	so = (struct socket *)fp->f_data;	if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING))		return (EALREADY);	if (error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME))		return (error);	error = soconnect(so, nam);	if (error)		goto bad;	if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {		m_freem(nam);		return (EINPROGRESS);	}	s = splnet();	while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)		if (error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,		    netcon, 0))			break;	if (error == 0) {		error = so->so_error;		so->so_error = 0;	}	splx(s);bad:	so->so_state &= ~SS_ISCONNECTING;	m_freem(nam);	if (error == ERESTART)		error = EINTR;	return (error);}#ifndef PROMsocketpair(p, uap, retval)	struct proc *p;	register struct args {		int	domain;		int	type;		int	protocol;		int	*rsv;	} *uap;	int retval[];{	register struct filedesc *fdp = p->p_fd;	struct file *fp1, *fp2;	struct socket *so1, *so2;	int fd, error, sv[2];	if (error = socreate(uap->domain, &so1, uap->type, uap->protocol))		return (error);	if (error = socreate(uap->domain, &so2, uap->type, uap->protocol))		goto free1;	if (error = falloc(p, &fp1, &fd))		goto free2;	sv[0] = fd;	fp1->f_flag = FREAD|FWRITE;	fp1->f_type = DTYPE_SOCKET;	fp1->f_ops = &socketops;	fp1->f_data = (caddr_t)so1;	if (error = falloc(p, &fp2, &fd))		goto free3;	fp2->f_flag = FREAD|FWRITE;	fp2->f_type = DTYPE_SOCKET;	fp2->f_ops = &socketops;	fp2->f_data = (caddr_t)so2;	sv[1] = fd;	if (error = soconnect2(so1, so2))		goto free4;	if (uap->type == SOCK_DGRAM) {		/*		 * Datagram socket connection is asymmetric.		 */		 if (error = soconnect2(so2, so1))			goto free4;	}	error = copyout((caddr_t)sv, (caddr_t)uap->rsv, 2 * sizeof (int));	retval[0] = sv[0];		/* XXX ??? */	retval[1] = sv[1];		/* XXX ??? */	return (error);free4:	ffree(fp2);	fdp->fd_ofiles[sv[1]] = 0;free3:	ffree(fp1);	fdp->fd_ofiles[sv[0]] = 0;free2:	(void)soclose(so2);free1:	(void)soclose(so1);	return (error);}#endifSYSCALL(sendto)(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	s;		caddr_t	buf;		int	len;		int	flags;		caddr_t	to;		int	tolen;	} *uap = v;	struct msghdr msg;	struct iovec aiov;	int error;	msg.msg_name = uap->to;	msg.msg_namelen = uap->tolen;	msg.msg_iov = &aiov;	msg.msg_iovlen = 1;	msg.msg_control = 0;#ifdef COMPAT_43	msg.msg_flags = 0;#endif	aiov.iov_base = uap->buf;	aiov.iov_len = uap->len;	return (sendit(p, uap->s, &msg, uap->flags, retval));}#ifdef COMPAT_43SYSCALL(osend)(p, uap, retval)	struct proc *p;	register struct args {		int	s;		caddr_t	buf;		int	len;		int	flags;	} *uap;	int *retval;{	struct msghdr msg;	struct iovec aiov;	msg.msg_name = 0;	msg.msg_namelen = 0;	msg.msg_iov = &aiov;	msg.msg_iovlen = 1;	aiov.iov_base = uap->buf;	aiov.iov_len = uap->len;	msg.msg_control = 0;	msg.msg_flags = 0;	return (sendit(p, uap->s, &msg, uap->flags, retval));}#define MSG_COMPAT	0x8000SYSCALL(osendmsg)(p, uap, retval)	struct proc *p;	register struct args {		int	s;		caddr_t	msg;		int	flags;	} *uap;	int *retval;{	struct msghdr msg;	struct iovec aiov[UIO_SMALLIOV], *iov;	int error;	if (error = copyin(uap->msg, (caddr_t)&msg, sizeof (struct omsghdr)))		return (error);	if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {		if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)			return (EMSGSIZE);		MALLOC(iov, struct iovec *,		      sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV, 		      M_WAITOK);	} else		iov = aiov;	if (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,	    (unsigned)(msg.msg_iovlen * sizeof (struct iovec))))		goto done;	msg.msg_flags = MSG_COMPAT;	msg.msg_iov = iov;	error = sendit(p, uap->s, &msg, uap->flags, retval);done:	if (iov != aiov)		FREE(iov, M_IOV);	return (error);}#endifSYSCALL(sendmsg)(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	s;		caddr_t	msg;		int	flags;	} *uap = v;	struct msghdr msg;	struct iovec aiov[UIO_SMALLIOV], *iov;	int error;	if (error = copyin(uap->msg, (caddr_t)&msg, sizeof (msg)))		return (error);	if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {		if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)			return (EMSGSIZE);		MALLOC(iov, struct iovec *,		       sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,		       M_WAITOK);	} else		iov = aiov;	if (msg.msg_iovlen &&	    (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,	    (unsigned)(msg.msg_iovlen * sizeof (struct iovec)))))		goto done;	msg.msg_iov = iov;#ifdef COMPAT_43	msg.msg_flags = 0;#endif	error = sendit(p, uap->s, &msg, uap->flags, retval);done:	if (iov != aiov)		FREE(iov, M_IOV);	return (error);}sendit(p, s, mp, flags, retsize)	register struct proc *p;	int s;	register struct msghdr *mp;	int flags, *retsize;{	struct file *fp;	struct uio auio;	register struct iovec *iov;	register int i;	struct mbuf *to, *control;	int len, error;#ifdef KTRACE	struct iovec *ktriov = NULL;#endif		if (error = getsock(p->p_fd, s, &fp))		return (error);	auio.uio_iov = mp->msg_iov;	auio.uio_iovcnt = mp->msg_iovlen;	auio.uio_segflg = UIO_USERSPACE;	auio.uio_rw = UIO_WRITE;	auio.uio_procp = p;	auio.uio_offset = 0;			/* XXX */	auio.uio_resid = 0;	iov = mp->msg_iov;	for (i = 0; i < mp->msg_iovlen; i++, iov++) {		if (iov->iov_len < 0)			return (EINVAL);		if ((auio.uio_resid += iov->iov_len) < 0)			return (EINVAL);	}	if (mp->msg_name) {		if (error = sockargs(&to, mp->msg_name, mp->msg_namelen,		    MT_SONAME))			return (error);	} else		to = 0;	if (mp->msg_control) {		if (mp->msg_controllen < sizeof(struct cmsghdr)#ifdef COMPAT_43		    && mp->msg_flags != MSG_COMPAT#endif		) {			error = EINVAL;			goto bad;		}		if (error = sockargs(&control, mp->msg_control,		    mp->msg_controllen, MT_CONTROL))			goto bad;#ifdef COMPAT_43		if (mp->msg_flags == MSG_COMPAT) {			register struct cmsghdr *cm;			M_PREPEND(control, sizeof(*cm), M_WAIT);			if (control == 0) {				error = ENOBUFS;				goto bad;			} else {				cm = mtod(control, struct cmsghdr *);				cm->cmsg_len = control->m_len;				cm->cmsg_level = SOL_SOCKET;				cm->cmsg_type = SCM_RIGHTS;			}		}#endif	} else		control = 0;#ifdef KTRACE	if (KTRPOINT(p, KTR_GENIO)) {		int iovlen = auio.uio_iovcnt * sizeof (struct iovec);		MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);		bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);	}#endif	len = auio.uio_resid;	if (error = sosend((struct socket *)fp->f_data, to, &auio,	    (struct mbuf *)0, control, flags)) {		if (auio.uio_resid != len && (error == ERESTART ||		    error == EINTR || error == EWOULDBLOCK))			error = 0;		if (error == EPIPE)			psignal(p, SIGPIPE);	}	if (error == 0)		*retsize = len - auio.uio_resid;#ifdef KTRACE	if (ktriov != NULL) {		if (error == 0)			ktrgenio(p->p_tracep, s, UIO_WRITE,				ktriov, *retsize, error);		FREE(ktriov, M_TEMP);	}#endifbad:	if (to)		m_freem(to);	return (error);}#ifdef COMPAT_43SYSCALL(orecvfrom)(p, uap, retval)	struct proc *p;	struct args {		int	s;		caddr_t	buf;		int	len;		int	flags;		caddr_t	from;		int	*fromlenaddr;	} *uap;	int *retval;{	uap->flags |= MSG_COMPAT;	return (SYSCALL(recvfrom)(p, uap, retval));}#endifSYSCALL(recvfrom)(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	s;		caddr_t	buf;		int	len;		int	flags;		caddr_t	from;		int	*fromlenaddr;	} *uap = v;	struct msghdr msg;	struct iovec aiov;

⌨️ 快捷键说明

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