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

📄 uipc_syscalls.c

📁 很好的一个嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
	int error;	if (uap->fromlenaddr) {		if (error = copyin((caddr_t)uap->fromlenaddr,		    (caddr_t)&msg.msg_namelen, sizeof (msg.msg_namelen)))			return (error);	} else		msg.msg_namelen = 0;	msg.msg_name = uap->from;	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 = uap->flags;	return (recvit(p, uap->s, &msg, (caddr_t)uap->fromlenaddr, retval));}#ifdef COMPAT_43SYSCALL(orecv)(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 = uap->flags;	return (recvit(p, uap->s, &msg, (caddr_t)0, retval));}/* * Old recvmsg.  This code takes advantage of the fact that the old msghdr * overlays the new one, missing only the flags, and with the (old) access * rights where the control fields are now. */SYSCALL(orecvmsg)(p, uap, retval)	struct proc *p;	register struct args {		int	s;		struct	omsghdr *msg;		int	flags;	} *uap;	int *retval;{	struct msghdr msg;	struct iovec aiov[UIO_SMALLIOV], *iov;	int error;	if (error = copyin((caddr_t)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;	msg.msg_flags = uap->flags | MSG_COMPAT;	if (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,	    (unsigned)(msg.msg_iovlen * sizeof (struct iovec))))		goto done;	msg.msg_iov = iov;	error = recvit(p, uap->s, &msg, (caddr_t)&uap->msg->msg_namelen, retval);	if (msg.msg_controllen && error == 0)		error = copyout((caddr_t)&msg.msg_controllen,		    (caddr_t)&uap->msg->msg_accrightslen, sizeof (int));done:	if (iov != aiov)		FREE(iov, M_IOV);	return (error);}#endifSYSCALL(recvmsg)(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	s;		struct	msghdr *msg;		int	flags;	} *uap = v;	struct msghdr msg;	struct iovec aiov[UIO_SMALLIOV], *uiov, *iov;	register int error;	if (error = copyin((caddr_t)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;#ifdef COMPAT_43	msg.msg_flags = uap->flags &~ MSG_COMPAT;#else	msg.msg_flags = uap->flags;#endif	uiov = msg.msg_iov;	msg.msg_iov = iov;	if (error = copyin((caddr_t)uiov, (caddr_t)iov,	    (unsigned)(msg.msg_iovlen * sizeof (struct iovec))))		goto done;	if ((error = recvit(p, uap->s, &msg, (caddr_t)0, retval)) == 0) {		msg.msg_iov = uiov;		error = copyout((caddr_t)&msg, (caddr_t)uap->msg, sizeof(msg));	}done:	if (iov != aiov)		FREE(iov, M_IOV);	return (error);}recvit(p, s, mp, namelenp, retsize)	register struct proc *p;	int s;	register struct msghdr *mp;	caddr_t namelenp;	int *retsize;{	struct file *fp;	struct uio auio;	register struct iovec *iov;	register int i;	int len, error;	struct mbuf *from = 0, *control = 0;#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_READ;	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);	}#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 = soreceive((struct socket *)fp->f_data, &from, &auio,	    (struct mbuf **)0, &control, &mp->msg_flags)) {		if (auio.uio_resid != len && (error == ERESTART ||		    error == EINTR || error == EWOULDBLOCK))			error = 0;	}#ifdef KTRACE	if (ktriov != NULL) {		if (error == 0)			ktrgenio(p->p_tracep, s, UIO_READ,				ktriov, len - auio.uio_resid, error);		FREE(ktriov, M_TEMP);	}#endif	if (error)		goto out;	*retsize = len - auio.uio_resid;	if (mp->msg_name) {		len = mp->msg_namelen;		if (len <= 0 || from == 0)			len = 0;		else {#ifdef COMPAT_43			if (mp->msg_flags & MSG_COMPAT)				mtod(from, struct osockaddr *)->sa_family =				    mtod(from, struct sockaddr *)->sa_family;#endif			if (len > from->m_len)				len = from->m_len;			/* else if len < from->m_len ??? */			if (error = copyout(mtod(from, caddr_t),			    (caddr_t)mp->msg_name, (unsigned)len))				goto out;		}		mp->msg_namelen = len;		if (namelenp &&		    (error = copyout((caddr_t)&len, namelenp, sizeof (int)))) {#ifdef COMPAT_43			if (mp->msg_flags & MSG_COMPAT)				error = 0;	/* old recvfrom didn't check */			else#endif			goto out;		}	}	if (mp->msg_control) {#ifdef	COMPAT_43		/*		 * We assume that old recvmsg calls won't receive access		 * rights and other control info, esp. as control info		 * is always optional and those options didn't exist in 4.3.		 * If we receive rights, trim the cmsghdr; anything else		 * is tossed.		 */		if (control && mp->msg_flags & MSG_COMPAT) {			if (mtod(control, struct cmsghdr *)->cmsg_level !=			    SOL_SOCKET ||			    mtod(control, struct cmsghdr *)->cmsg_type !=			    SCM_RIGHTS) {				mp->msg_controllen = 0;				goto out;			}			control->m_len -= sizeof (struct cmsghdr);			control->m_data += sizeof (struct cmsghdr);		}#endif		len = mp->msg_controllen;		if (len <= 0 || control == 0)			len = 0;		else {			if (len >= control->m_len)				len = control->m_len;			else				mp->msg_flags |= MSG_CTRUNC;			error = copyout((caddr_t)mtod(control, caddr_t),			    (caddr_t)mp->msg_control, (unsigned)len);		}		mp->msg_controllen = len;	}out:	if (from)		m_freem(from);	if (control)		m_freem(control);	return (error);}/* ARGSUSED */SYSCALL(shutdown)(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	s;		int	how;	} *uap = v;	struct file *fp;	int error;	if (error = getsock(p->p_fd, uap->s, &fp))		return (error);	return (soshutdown((struct socket *)fp->f_data, uap->how));}/* ARGSUSED */SYSCALL(setsockopt)(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	s;		int	level;		int	name;		caddr_t	val;		int	valsize;	} *uap = v;	struct file *fp;	struct mbuf *m = NULL;	int error;	if (error = getsock(p->p_fd, uap->s, &fp))		return (error);	if (uap->valsize > MLEN)		return (EINVAL);	if (uap->val) {		m = m_get(M_WAIT, MT_SOOPTS);		if (m == NULL)			return (ENOBUFS);		if (error = copyin(uap->val, mtod(m, caddr_t),		    (u_int)uap->valsize)) {			(void) m_free(m);			return (error);		}		m->m_len = uap->valsize;	}	return (sosetopt((struct socket *)fp->f_data, uap->level,	    uap->name, m));}/* ARGSUSED */SYSCALL(getsockopt)(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	s;		int	level;		int	name;		caddr_t	val;		int	*avalsize;	} *uap = v;	struct file *fp;	struct mbuf *m = NULL;	int valsize, error;	if (error = getsock(p->p_fd, uap->s, &fp))		return (error);	if (uap->val) {		if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,		    sizeof (valsize)))			return (error);	} else		valsize = 0;	if ((error = sogetopt((struct socket *)fp->f_data, uap->level,	    uap->name, &m)) == 0 && uap->val && valsize && m != NULL) {		if (valsize > m->m_len)			valsize = m->m_len;		error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);		if (error == 0)			error = copyout((caddr_t)&valsize,			    (caddr_t)uap->avalsize, sizeof (valsize));	}	if (m != NULL)		(void) m_free(m);	return (error);}#ifndef PROM/* ARGSUSED */pipe(p, uap, retval)	struct proc *p;	struct args *uap;	int retval[];{	register struct filedesc *fdp = p->p_fd;	struct file *rf, *wf;	struct socket *rso, *wso;	int fd, error;	if (error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0))		return (error);	if (error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0))		goto free1;	if (error = falloc(p, &rf, &fd))		goto free2;	retval[0] = fd;	rf->f_flag = FREAD;	rf->f_type = DTYPE_SOCKET;	rf->f_ops = &socketops;	rf->f_data = (caddr_t)rso;	if (error = falloc(p, &wf, &fd))		goto free3;	wf->f_flag = FWRITE;	wf->f_type = DTYPE_SOCKET;	wf->f_ops = &socketops;	wf->f_data = (caddr_t)wso;	retval[1] = fd;	if (error = unp_connect2(wso, rso))		goto free4;	return (0);free4:	ffree(wf);	fdp->fd_ofiles[retval[1]] = 0;free3:	ffree(rf);	fdp->fd_ofiles[retval[0]] = 0;free2:	(void)soclose(wso);free1:	(void)soclose(rso);	return (error);}#endif/* * Get socket name. */#ifdef COMPAT_43SYSCALL(getsockname)(p, uap, retval)	struct proc *p;	struct args {		int	fdes;		caddr_t	asa;		int	*alen;		int	compat_43;	} *uap;	int *retval;{	uap->compat_43 = 0;	return (getsockname1(p, uap, retval));}SYSCALL(ogetsockname)(p, uap, retval)	struct proc *p;	struct args {		int	fdes;		caddr_t	asa;		int	*alen;		int	compat_43;	} *uap;	int *retval;{	uap->compat_43 = 1;	return (getsockname1(p, uap, retval));}#else /* COMPAT_43 */#define	getsockname1	SYSCALL(getsockname)#endif/* ARGSUSED */getsockname1(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	fdes;		caddr_t	asa;		int	*alen;#ifdef COMPAT_43		int	compat_43;#endif	} *uap = v;	struct file *fp;	register struct socket *so;	struct mbuf *m;	int len, error;	if (error = getsock(p->p_fd, uap->fdes, &fp))		return (error);	if (error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)))		return (error);	so = (struct socket *)fp->f_data;	m = m_getclr(M_WAIT, MT_SONAME);	if (m == NULL)		return (ENOBUFS);	if (error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0))		goto bad;	if (len > m->m_len)		len = m->m_len;#ifdef COMPAT_43	if (uap->compat_43)		mtod(m, struct osockaddr *)->sa_family =		    mtod(m, struct sockaddr *)->sa_family;#endif	error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len);	if (error == 0)		error = copyout((caddr_t)&len, (caddr_t)uap->alen,		    sizeof (len));bad:	m_freem(m);	return (error);}/* * Get name of peer for connected socket. */#ifdef COMPAT_43SYSCALL(getpeername)(p, uap, retval)	struct proc *p;	struct args {		int	fdes;		caddr_t	asa;		int	*alen;		int	compat_43;	} *uap;	int *retval;{	uap->compat_43 = 0;	return (getpeername1(p, uap, retval));}SYSCALL(ogetpeername)(p, uap, retval)	struct proc *p;	struct args {		int	fdes;		caddr_t	asa;		int	*alen;		int	compat_43;	} *uap;	int *retval;{	uap->compat_43 = 1;	return (getpeername1(p, uap, retval));}#else /* COMPAT_43 */#define	getpeername1	SYSCALL(getpeername)#endif/* ARGSUSED */getpeername1(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	fdes;		caddr_t	asa;		int	*alen;#ifdef COMPAT_43		int	compat_43;#endif	} *uap = v;	struct file *fp;	register struct socket *so;	struct mbuf *m;	int len, error;	if (error = getsock(p->p_fd, uap->fdes, &fp))		return (error);	so = (struct socket *)fp->f_data;	if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)		return (ENOTCONN);	m = m_getclr(M_WAIT, MT_SONAME);	if (m == NULL)		return (ENOBUFS);	if (error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)))		return (error);	if (error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0))		goto bad;	if (len > m->m_len)		len = m->m_len;#ifdef COMPAT_43	if (uap->compat_43)		mtod(m, struct osockaddr *)->sa_family =		    mtod(m, struct sockaddr *)->sa_family;#endif	if (error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len))		goto bad;	error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len));bad:	m_freem(m);	return (error);}sockargs(mp, buf, buflen, type)	struct mbuf **mp;	caddr_t buf;	int buflen, type;{	register struct mbuf *m;	int error;	if ((u_int)buflen > MLEN) {#ifdef COMPAT_43		if (type == MT_SONAME && (u_int)buflen <= 112)			buflen = MLEN;		/* unix domain compat. hack */		else#endif		return (EINVAL);	}	m = m_get(M_WAIT, type);	if (m == NULL)		return (ENOBUFS);	m->m_len = buflen;	error = copyin(buf, mtod(m, caddr_t), (u_int)buflen);	if (error)		(void) m_free(m);	else		*mp = m;	if (type == MT_SONAME) {		register struct sockaddr *sa = mtod(m, struct sockaddr *);#if defined(COMPAT_43) && BYTE_ORDER != BIG_ENDIAN		if (sa->sa_family == 0 && sa->sa_len < AF_MAX)			sa->sa_family = sa->sa_len;#endif		sa->sa_len = buflen;	}	return (error);}getsock(fdp, fdes, fpp)	struct filedesc *fdp;	int fdes;	struct file **fpp;{	register struct file *fp;	if ((unsigned)fdes >= fdp->fd_nfiles ||	    (fp = fdp->fd_ofiles[fdes]) == NULL)		return (EBADF);	if (fp->f_type != DTYPE_SOCKET)		return (ENOTSOCK);	*fpp = fp;	return (0);}

⌨️ 快捷键说明

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