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

📄 uipc_syscalls.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	$Id: uipc_syscalls.c,v 1.1.1.1 2001/10/01 18:47:35 patrik Exp $ *//*	$OpenBSD: uipc_syscalls.c,v 1.28 1999/07/13 15:17:51 provos Exp $	*//*	$NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $	*//* * Copyright (c) 1982, 1986, 1989, 1990, 1993 *	The 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	8.4 (Berkeley) 2/21/94 */#include <sys/param.h>#include <sys/systm.h>#include <sys/filedesc.h>#include <sys/proc.h>#include <sys/file.h>#include <sys/buf.h>#include <sys/malloc.h>#include <sys/mbuf.h>#include <sys/protosw.h>#include <sys/socket.h>#include <sys/socketvar.h>#include <sys/signalvar.h>#if 0#include <sys/un.h>#endif#ifdef KTRACE#include <sys/ktrace.h>#endif#if 0#include <sys/mount.h>#endif#include <sys/syscallargs.h>/* * System call interface to the socket abstraction. */extern	struct fileops socketops;intsys_socket(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_socket_args /* {		syscallarg(int) domain;		syscallarg(int) type;		syscallarg(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)) != 0)		return (error);	fp->f_flag = FREAD|FWRITE;	fp->f_type = DTYPE_SOCKET;	fp->f_ops = &socketops;	error = socreate(SCARG(uap, domain), &so, SCARG(uap, type),			 SCARG(uap, protocol));	if (error) {		fdremove(fdp, fd);		ffree(fp);	} else {		fp->f_data = (caddr_t)so;		*retval = fd;	}	return (error);}/* ARGSUSED */intsys_bind(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_bind_args /* {		syscallarg(int) s;		syscallarg(struct sockaddr *) name;		syscallarg(socklen_t) namelen;	} */ *uap = v;	struct file *fp;	struct mbuf *nam;	int error;	if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)		return (error);	error = sockargs(&nam, (caddr_t)SCARG(uap, name), SCARG(uap, namelen),			 MT_SONAME);	if (error)		return (error);	error = sobind((struct socket *)fp->f_data, nam);	m_freem(nam);	return (error);}/* ARGSUSED */intsys_listen(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_listen_args /* {		syscallarg(int) s;		syscallarg(int) backlog;	} */ *uap = v;	struct file *fp;	int error;	if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)		return (error);	return (solisten((struct socket *)fp->f_data, SCARG(uap, backlog)));}intsys_accept(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_accept_args /* {		syscallarg(int) s;		syscallarg(struct sockaddr *) name;		syscallarg(socklen_t *) anamelen;	} */ *uap = v;	struct file *fp;	struct mbuf *nam;	socklen_t namelen;	int error, s, tmpfd;	register struct socket *so;	if (SCARG(uap, name) && (error = copyin((caddr_t)SCARG(uap, anamelen),	    (caddr_t)&namelen, sizeof (namelen))))		return (error);	if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)		return (error);	s = splsoftnet();	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;		}		error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,			       netcon, 0);		if (error) {			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, &tmpfd)) != 0) {		splx(s);		return (error);	}	*retval = tmpfd;	{ 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 (SCARG(uap, name)) {		if (namelen > nam->m_len)			namelen = nam->m_len;		/* SHOULD COPY OUT A CHAIN HERE */		if ((error = copyout(mtod(nam, caddr_t),		    (caddr_t)SCARG(uap, name), namelen)) == 0)			error = copyout((caddr_t)&namelen,			    (caddr_t)SCARG(uap, anamelen),			    sizeof (*SCARG(uap, anamelen)));	}	m_freem(nam);	splx(s);	return (error);}/* ARGSUSED */intsys_connect(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_connect_args /* {		syscallarg(int) s;		syscallarg(struct sockaddr *) name;		syscallarg(socklen_t) namelen;	} */ *uap = v;	struct file *fp;	register struct socket *so;	struct mbuf *nam;	int error, s;	if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)		return (error);	so = (struct socket *)fp->f_data;	if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING))		return (EALREADY);	error = sockargs(&nam, (caddr_t)SCARG(uap, name), SCARG(uap, namelen),			 MT_SONAME);	if (error)		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 = splsoftnet();	while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {		error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,			       netcon, 0);		if (error)			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);}#ifdef NOTUSED_BY_PMONintsys_socketpair(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_socketpair_args /* {		syscallarg(int) domain;		syscallarg(int) type;		syscallarg(int) protocol;		syscallarg(int *) rsv;	} */ *uap = v;	register struct filedesc *fdp = p->p_fd;	struct file *fp1, *fp2;	struct socket *so1, *so2;	int fd, error, sv[2];	error = socreate(SCARG(uap, domain), &so1, SCARG(uap, type),			 SCARG(uap, protocol));	if (error)		return (error);	error = socreate(SCARG(uap, domain), &so2, SCARG(uap, type),			 SCARG(uap, protocol));	if (error)		goto free1;	if ((error = falloc(p, &fp1, &fd)) != 0)		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)) != 0)		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)) != 0)		goto free4;	if (SCARG(uap, type) == SOCK_DGRAM) {		/*		 * Datagram socket connection is asymmetric.		 */		 if ((error = soconnect2(so2, so1)) != 0)			goto free4;	}	error = copyout((caddr_t)sv, (caddr_t)SCARG(uap, rsv),	    2 * sizeof (int));	if (error == 0)		return (error);free4:	ffree(fp2);	fdremove(fdp, sv[1]);free3:	ffree(fp1);	fdremove(fdp, sv[0]);free2:	(void)soclose(so2);free1:	(void)soclose(so1);	return (error);}#endif /* NOTUSED_BU_PMON */intsys_sendto(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_sendto_args /* {		syscallarg(int) s;		syscallarg(caddr_t) buf;		syscallarg(size_t) len;		syscallarg(int) flags;		syscallarg(struct sockaddr *) to;		syscallarg(socklen_t) tolen;	} */ *uap = v;	struct msghdr msg;	struct iovec aiov;	msg.msg_name = (caddr_t)SCARG(uap, to);	msg.msg_namelen = SCARG(uap, tolen);	msg.msg_iov = &aiov;	msg.msg_iovlen = 1;	msg.msg_control = 0;#ifdef COMPAT_OLDSOCK	msg.msg_flags = 0;#endif	aiov.iov_base = (char *)SCARG(uap, buf);	aiov.iov_len = SCARG(uap, len);	return (sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval));}intsys_sendmsg(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_sendmsg_args /* {		syscallarg(int) s;		syscallarg(caddr_t) msg;		syscallarg(int) flags;	} */ *uap = v;	struct msghdr msg;	struct iovec aiov[UIO_SMALLIOV], *iov;	int error;	error = copyin(SCARG(uap, msg), (caddr_t)&msg, sizeof (msg));	if (error)		return (error);	if (msg.msg_iovlen <= 0 || msg.msg_iovlen > IOV_MAX)		return (EMSGSIZE);	if (msg.msg_iovlen > UIO_SMALLIOV)		MALLOC(iov, struct iovec *,		       sizeof(struct iovec) * 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_OLDSOCK	msg.msg_flags = 0;#endif	error = sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval);done:	if (iov != aiov)		FREE(iov, M_IOV);	return (error);}intsendit(p, s, mp, flags, retsize)	register struct proc *p;	int s;	register struct msghdr *mp;	int flags;	register_t *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)) != 0)		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++) {		/* Don't allow sum > SSIZE_MAX */		if (iov->iov_len > SSIZE_MAX ||		    (auio.uio_resid += iov->iov_len) > SSIZE_MAX)			return (EINVAL);	}	if (mp->msg_name) {		error = sockargs(&to, mp->msg_name, mp->msg_namelen,				 MT_SONAME);		if (error)			return (error);	} else		to = 0;	if (mp->msg_control) {		if (mp->msg_controllen < sizeof(struct cmsghdr)#ifdef COMPAT_OLDSOCK		    && mp->msg_flags != MSG_COMPAT#endif		) {			error = EINVAL;			goto bad;		}		error = sockargs(&control, mp->msg_control,				 mp->msg_controllen, MT_CONTROL);		if (error)			goto bad;#ifdef COMPAT_OLDSOCK		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;	error = sosend((struct socket *)fp->f_data, to, &auio,		       NULL, control, flags);	if (error) {		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);}intsys_recvfrom(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_recvfrom_args /* {		syscallarg(int) s;		syscallarg(caddr_t) buf;		syscallarg(size_t) len;		syscallarg(int) flags;

⌨️ 快捷键说明

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