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

📄 uipc_sock.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
				*controlp = m_copy(m, 0, m->m_len);			m = m->m_next;		} else {			sbfree(&so->so_rcv, m);			if (controlp) {				if (pr->pr_domain->dom_externalize &&				    mtod(m, struct cmsghdr *)->cmsg_type ==				    SCM_RIGHTS)				   error = (*pr->pr_domain->dom_externalize)(m);				*controlp = m;				so->so_rcv.sb_mb = m->m_next;				m->m_next = 0;				m = so->so_rcv.sb_mb;			} else {				so->so_rcv.sb_mb = m_free(m);				m = so->so_rcv.sb_mb;			}		}		if (controlp) {			orig_resid = 0;			controlp = &(*controlp)->m_next;		}	}	if (m) {		if ((flags & MSG_PEEK) == 0)			m->m_nextpkt = nextrecord;		type = m->m_type;		if (type == MT_OOBDATA)			flags |= MSG_OOB;	}	moff = 0;	offset = 0;	while (m && uio->uio_resid > 0 && error == 0) {		if (m->m_type == MT_OOBDATA) {			if (type != MT_OOBDATA)				break;		} else if (type == MT_OOBDATA)			break;#ifdef DIAGNOSTIC		else if (m->m_type != MT_DATA && m->m_type != MT_HEADER)			panic("receive 3");#endif		so->so_state &= ~SS_RCVATMARK;		len = uio->uio_resid;		if (so->so_oobmark && len > so->so_oobmark - offset)			len = so->so_oobmark - offset;		if (len > m->m_len - moff)			len = m->m_len - moff;		/*		 * If mp is set, just pass back the mbufs.		 * Otherwise copy them out via the uio, then free.		 * Sockbuf must be consistent here (points to current mbuf,		 * it points to next record) when we drop priority;		 * we must note any additions to the sockbuf when we		 * block interrupts again.		 */		if (mp == 0) {			error = uiomove(mtod(m, caddr_t) + moff, (int)len, uio);		} else			uio->uio_resid -= len;		if (len == m->m_len - moff) {			if (m->m_flags & M_EOR)				flags |= MSG_EOR;			if (flags & MSG_PEEK) {				m = m->m_next;				moff = 0;			} else {				nextrecord = m->m_nextpkt;				sbfree(&so->so_rcv, m);				if (mp) {					*mp = m;					mp = &m->m_next;					so->so_rcv.sb_mb = m = m->m_next;					*mp = (struct mbuf *)0;				} else {					so->so_rcv.sb_mb = m_free(m);					m = so->so_rcv.sb_mb;				}				if (m)					m->m_nextpkt = nextrecord;			}		} else {			if (flags & MSG_PEEK)				moff += len;			else {				if (mp)                                    {				    *mp = m_copym(m, 0, len, M_WAIT);                                    if (*mp == NULL)                                        {                                        error = ENOBUFS;                                        goto release;                                        }                                    }				m->m_data += len;				m->m_len -= len;				so->so_rcv.sb_cc -= len;			}		}		if (so->so_oobmark) {			if ((flags & MSG_PEEK) == 0) {				so->so_oobmark -= len;				if (so->so_oobmark == 0) {					so->so_state |= SS_RCVATMARK;					break;				}			} else {				offset += len;				if (offset == so->so_oobmark)					break;			}		}		if (flags & MSG_EOR)			break;		/*		 * If the MSG_WAITALL flag is set (for non-atomic socket),		 * we must not quit until "uio->uio_resid == 0" or an error		 * termination.  If a signal/timeout occurs, return		 * with a short count but without error.		 * Keep sockbuf locked against other readers.		 */		while (flags & MSG_WAITALL && m == 0 && uio->uio_resid > 0 &&		    !sosendallatonce(so) && !nextrecord) {			if (so->so_error || so->so_state & SS_CANTRCVMORE)				break;			sbwait(&so->so_rcv);			if ((m = so->so_rcv.sb_mb))				nextrecord = m->m_nextpkt;		}	}	if (m && pr->pr_flags & PR_ATOMIC) {		flags |= MSG_TRUNC;		if ((flags & MSG_PEEK) == 0)			(void) sbdroprecord(&so->so_rcv);	}	if ((flags & MSG_PEEK) == 0) {		if (m == 0)			so->so_rcv.sb_mb = nextrecord;		if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)			(*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,			    (struct mbuf *)(long)flags, (struct mbuf *)0,			    (struct mbuf *)0);	}	if (orig_resid == uio->uio_resid && orig_resid &&	    (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {		goto restart;	}			if (flagsp)		*flagsp |= flags;release:	splx(s);	if (error != 0)            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */            WV_NET_EVENT_2 (NET_CORE_EVENT, WV_NET_CRITICAL, 35, 5,                            WV_NETEVENT_SORECV_FAIL, WV_NET_RECV,                            so->so_fd, error)#endif  /* INCLUDE_WVNET */#endif	    netErrnoSet (error);            }#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */        else            {            WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_VERBOSE, 55, 21,                            WV_NETEVENT_SORECV_FINISH, WV_NET_RECV, so->so_fd)            }#endif  /* INCLUDE_WVNET */#endif	return (error);}intsoshutdown(so, how)	register struct socket *so;	register int how;{	register struct protosw *pr = so->so_proto;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */    WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_VERBOSE, 56, 22,                     WV_NETEVENT_SOSHUTDOWN_START, so->so_fd, how)#endif  /* INCLUDE_WVNET */#endif	how++;	if (how & 1)		/* <=> FREAD of BSD44 */		sorflush(so);		if (how & 2)		/* <=> FWRITE of BSD44 */		return ((*pr->pr_usrreq)(so, PRU_SHUTDOWN,		    (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0));	return (0);}voidsorflush(so)	register struct socket *so;{	register struct sockbuf *sb = &so->so_rcv;	register struct protosw *pr = so->so_proto;	register int s;	struct sockbuf asb;	sb->sb_flags |= SB_NOINTR;	s = splimp();	socantrcvmore(so);	asb = *sb;        if (sb->sb_Sem)            {	    semDelete (sb->sb_Sem);            sb->sb_Sem = NULL;            }	bzero((caddr_t)sb, sizeof (*sb));	splx(s);	if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose)		(*pr->pr_domain->dom_dispose)(asb.sb_mb);	sbrelease(&asb);}intsosetopt(so, level, optname, m0)	register struct socket *so;	int level, optname;	struct mbuf *m0;{	int error = 0;	register struct mbuf *m = m0;	if (level != SOL_SOCKET) {		if (so->so_proto && so->so_proto->pr_ctloutput)			return ((*so->so_proto->pr_ctloutput)				  (PRCO_SETOPT, so, level, optname, &m0));		error = ENOPROTOOPT;	} else {		switch (optname) {		case SO_LINGER:			if (m == NULL || m->m_len != sizeof (struct linger)) {				error = EINVAL;				goto bad;			}			so->so_linger = mtod(m, struct linger *)->l_linger;			/* fall thru... */		case SO_DEBUG:		case SO_KEEPALIVE:		case SO_DONTROUTE:		case SO_USELOOPBACK:		case SO_BROADCAST:		case SO_REUSEADDR:		case SO_REUSEPORT:		case SO_OOBINLINE:                case SO_USEPATHMTU:			if (m == NULL || m->m_len < sizeof (int)) {				error = EINVAL;				goto bad;			}			if (*mtod(m, int *))				so->so_options |= optname;			else				so->so_options &= ~optname;			break;		case SO_SNDBUF:		case SO_RCVBUF:		case SO_SNDLOWAT:		case SO_RCVLOWAT:			if (m == NULL || m->m_len < sizeof (int)) {				error = EINVAL;				goto bad;			}			switch (optname) {			case SO_SNDBUF:			case SO_RCVBUF:				if (sbreserve(optname == SO_SNDBUF ?				    &so->so_snd : &so->so_rcv,				    (u_long) *mtod(m, int *)) == 0) {					error = ENOBUFS;					goto bad;				}				break;			case SO_SNDLOWAT:				so->so_snd.sb_lowat = *mtod(m, int *);				break;			case SO_RCVLOWAT:				so->so_rcv.sb_lowat = *mtod(m, int *);				break;			}			break;		case SO_SNDTIMEO:		case SO_RCVTIMEO:		    {			switch (optname) {			case SO_SNDTIMEO:				so->so_snd.sb_timeo = *mtod(m, int *);				break;			case SO_RCVTIMEO:				so->so_rcv.sb_timeo = *mtod(m, int *);				break;			}			break;		    }#ifdef VIRTUAL_STACK                case SO_VSID:                    so->vsid = *mtod(m, int *);                    break;#endif /* VIRTUAL_STACK */		default:			error = ENOPROTOOPT;			break;		}		if (error == 0 && so->so_proto && so->so_proto->pr_ctloutput) {			(void) ((*so->so_proto->pr_ctloutput)				  (PRCO_SETOPT, so, level, optname, &m0));			m = NULL;	/* freed by protocol */		}	}bad:	if (m)		(void) m_free(m);	return (error);}intsogetopt(so, level, optname, mp)	register struct socket *so;	int level, optname;	struct mbuf **mp;{	register struct mbuf *m;	if (level != SOL_SOCKET) {		if (so->so_proto && so->so_proto->pr_ctloutput) {			return ((*so->so_proto->pr_ctloutput)				  (PRCO_GETOPT, so, level, optname, mp));		} else			return (ENOPROTOOPT);	} else {		m = mBufClGet(M_WAIT, MT_SOOPTS, CL_SIZE_128, TRUE);                if (m == (struct mbuf *) NULL)                    return (ENOBUFS);		m->m_len = sizeof (int);		switch (optname) {		case SO_LINGER:			m->m_len = sizeof (struct linger);			mtod(m, struct linger *)->l_onoff =				so->so_options & SO_LINGER;			mtod(m, struct linger *)->l_linger = so->so_linger;			break;		case SO_USELOOPBACK:		case SO_DONTROUTE:		case SO_DEBUG:		case SO_KEEPALIVE:		case SO_REUSEADDR:		case SO_REUSEPORT:		case SO_BROADCAST:		case SO_OOBINLINE:			*mtod(m, int *) = so->so_options & optname;			break;		case SO_TYPE:			*mtod(m, int *) = so->so_type;			break;		case SO_ERROR:			*mtod(m, int *) = so->so_error;			so->so_error = 0;			break;		case SO_SNDBUF:			*mtod(m, int *) = so->so_snd.sb_hiwat;			break;		case SO_RCVBUF:			*mtod(m, int *) = so->so_rcv.sb_hiwat;			break;		case SO_SNDLOWAT:			*mtod(m, int *) = so->so_snd.sb_lowat;			break;		case SO_RCVLOWAT:			*mtod(m, int *) = so->so_rcv.sb_lowat;			break;		case SO_SNDTIMEO:		case SO_RCVTIMEO:		        *mtod(m, int *) = (optname == SO_SNDTIMEO ?			     so->so_snd.sb_timeo : so->so_rcv.sb_timeo);			break;#ifdef VIRTUAL_STACK                case SO_VSID:                        *mtod(m, int *) = so->vsid;                        break;#endif /* VIRTUAL_STACK */		default:			(void)m_free(m);			return (ENOPROTOOPT);		}		*mp = m;		return (0);	}}voidsohasoutofband(so)	register struct socket *so;{#ifdef UNIXBSD44	/* support for out of band data later on */			/* 			   This can be done by maintaining a taskId in the			   in the socket structure and posting a SIGURG to			   the task which would invoke the signal handler			   for SIGURG if that signal is registered properly			   The taskId should be created in the socket structure			   at the time of the creation of the socket.			   */	struct proc *p;	if (so->so_pgid < 0)		gsignal(-so->so_pgid, SIGURG);	else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0)		psignal(p, SIGURG);	selwakeup(&so->so_rcv.sb_sel);#endif /* UNIXBSD44 */}int uiomove(cp, n, uio)    register caddr_t cp;    register int n;    register struct uio *uio;    {    register struct iovec *iov;    u_int cnt;    int error = 0;#ifdef DIAGNOSTIC    if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE)	panic("uiomove: mode");    if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc)	panic("uiomove proc");#endif    while (n > 0 && uio->uio_resid) 	{	iov = uio->uio_iov;	cnt = iov->iov_len;	if (cnt == 0)	    {	    uio->uio_iov++;	    uio->uio_iovcnt--;	    continue;	    }	if (cnt > n)	    cnt = n;	if (uio->uio_rw == UIO_READ)	    bcopy((caddr_t)cp, iov->iov_base, cnt);	else	    bcopy(iov->iov_base, (caddr_t)cp, cnt);	iov->iov_base += cnt;	iov->iov_len -= cnt;	uio->uio_resid -= cnt;	uio->uio_offset += cnt;	cp += cnt;	n -= cnt;	}    return (error);    }

⌨️ 快捷键说明

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