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

📄 bsdsocklib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 4 页
字号:
#if (CPU == SIMHPPA)/* *  Set the size of the receive buffer. *  This is the way (without rewriting the user app) to get *  data from the master to auto-segment and fit in the pty. */{    int bLen = 660;    status = setsockopt (s, SOL_SOCKET, SO_RCVBUF, &bLen, sizeof (bLen));    if (status == ERROR)	return (ERROR);}#endif    status = soconnect (so, nam);    if (status)	{	netErrnoSet (status);	so->so_state &= ~SS_ISCONNECTING;	m_freem(nam);	return (ERROR);	}    slev = splnet();    if ((so->so_state & SS_NBIO) &&        (so->so_state & SS_ISCONNECTING))        {        netErrnoSet (EINPROGRESS);	splx (slev);	so->so_state &= ~SS_ISCONNECTING;	m_freem (nam);        return (ERROR);        }    while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)        ksleep (&so->so_timeoSem);    if (so->so_error)	{	netErrnoSet ((int) so->so_error);	so->so_error = 0;	splx (slev);	so->so_state &= ~SS_ISCONNECTING;	m_freem (nam);	return (ERROR);	}    splx (slev);    so->so_state &= ~SS_ISCONNECTING;    m_freem (nam);    return (OK);    }/******************************************************************************** bsdConnectWithTimeout - attempt a connection over a socket for a specified duration** This routine performs the same function as connect(); however, in addition,* users can specify how long to continue attempting the new connection.  ** If the <timeVal> is a NULL pointer, this routine performs exactly like* connect().  If <timeVal> is not NULL, it will attempt to establish a new* connection for the duration of the time specified in <timeVal>, after* which it will report a time-out error if the connection is not* established.** RETURNS: OK, or ERROR if a connection cannot be established.** SEE ALSO: connect()** NOMANUAL*/STATUS connectWithTimeout    (    int                 sock,           /* socket descriptor */    struct sockaddr     *adrs,          /* addr of the socket to connect */    int                 adrsLen,        /* length of the socket, in bytes */    struct timeval      *timeVal        /* time-out value */    )    {    int			on = 0;    fd_set		writeFds;    int			retVal = ERROR;    int			peerAdrsLen;    struct sockaddr	peerAdrs;    struct socket	*so;    if (timeVal == NULL)	return (connect (sock, adrs, adrsLen));    if ((so = (struct socket *) iosFdValue (sock)) == (struct socket *) ERROR)        return (ERROR);    if (!(so->so_state & SS_NBIO))	{	on = 1;	/* set NBIO to have the connect() return without pending */        if ((ioctl (sock, FIONBIO, (int) &on)) == ERROR)	    return (ERROR);	}    if (connect (sock, adrs, adrsLen) < 0)	{	/* when socket is set to non-blocking mode, connect() will return	 * with EINPROGRESS if a connection cannot be setup immediately.	 */	if ((errnoGet () & 0xffff) == EINPROGRESS)	    {	    /* We do synchronous polling on the write side of this socket	     * using select() with the given <timeVal> timeout value until	     * the connection gets established.	     */	    FD_ZERO (&writeFds);	    FD_SET (sock, &writeFds);	/* poll write-side of <sock> */	    if (select (FD_SETSIZE, (fd_set *) NULL, &writeFds,			(fd_set *) NULL, timeVal) > 0)		{		/* select() is successful, see if our socket is actually		 * selected for writing.		 */		if (FD_ISSET (sock, &writeFds))		    {		    /* connection attempt has completed.  we now see if		     * it was a successful attempt by trying to get the		     * remote peer's address.  If getpeername() succeeds		     * we have a connection, otherwise the connect() has		     * failed.		     */		    peerAdrsLen = sizeof (peerAdrs);		    if (getpeername (sock, &peerAdrs, &peerAdrsLen) != ERROR)			retVal = OK;		    }		}	    else		netErrnoSet (ETIMEDOUT);	    }	}    else	retVal = OK;    if (on)	{	on = 0;		/* turn OFF the non-blocking I/O */        if ((ioctl (sock, FIONBIO, (int) &on)) == ERROR)	    return (ERROR);	}    return (retVal);    }/********************************************************************************* bsdSendto - send a message to a socket** This routine sends a message to the datagram socket named by <to>.  The* socket <s> will be received by the receiver as the sending socket.* * The maximum length of <buf> is subject to the limits on UDP buffer* size; see the discussion of SO_SNDBUF in the setsockopt() manual* entry.** RETURNS* The number of bytes sent, or ERROR if the call fails.* * SEE ALSO* setsockopt()** NOMANUAL*/int sendto    (    FAST int             s,             /* socket to send data to */    FAST caddr_t         buf,           /* pointer to data buffer */    FAST int             bufLen,        /* length of buffer */    FAST int             flags,         /* flags to underlying protocols */    FAST struct sockaddr *to,           /* recipient's address */    FAST int             tolen          /* length of <to> sockaddr */    )    {    FAST struct socket 	*so;    FAST int		spl;    int			status;    struct mbuf		*mto;    int			len;		/* value/result */    struct uio		usrIo;		/* user IO structure */    struct iovec	ioVec;		/* IO vector structure */    struct mbuf *	pMbuf = NULL;	/* pointer to mbuf */    struct uio *	pUsrIo = NULL;	/* pointer to User IO structure */    /* extract the socket from the fd */    if ((so = (struct socket *) iosFdValue (s)) == (struct socket *) ERROR)	{	if ((flags & MSG_MBUF) && (buf))	    m_freem ((struct mbuf *)buf);        return (ERROR);	}    spl = splnet ();    status = bsdSockargs (&mto, (char *) to, tolen, MT_SONAME);    if (status)	{	netErrnoSet (status);	if ((flags & MSG_MBUF) && (buf))	    m_freem ((struct mbuf *)buf);        splx (spl);	return (ERROR);	}    if (flags & MSG_MBUF)	{	pMbuf = (struct mbuf *) buf; 	len = bufLen;	}    else	{	usrIo.uio_iov = &ioVec;	usrIo.uio_iovcnt = 1;	usrIo.uio_offset = 0;	usrIo.uio_resid = bufLen;	usrIo.uio_segflg = UIO_USERSPACE;	usrIo.uio_rw = UIO_WRITE;	ioVec.iov_base = (caddr_t) buf;	ioVec.iov_len = bufLen;	pUsrIo = &usrIo; 	len = usrIo.uio_resid;	}    status = sosend (so, mto,  pUsrIo, pMbuf, 0, flags);        m_free (mto);    splx (spl);    if (status)        {        if (pUsrIo != NULL && pUsrIo->uio_resid != len &&            (status == EINTR || status == EWOULDBLOCK))            status = OK;        }    return (status == OK ? ((pUsrIo == NULL) ? len : (len - pUsrIo->uio_resid))	    : ERROR);    }/********************************************************************************* bsdSend - send data to a socket** This routine transmits data to a previously established connection-based* (stream) socket.** The maximum length of <buf> is subject to the limits* on TCP buffer size; see the discussion of SO_SNDBUF in the* setsockopt() manual entry.** RETURNS* The number of bytes sent, or ERROR if the call fails.* * SEE ALSO* setsockopt()* ** NOMANUAL*/int send    (    FAST int            s,              /* socket to send to */    FAST char           *buf,           /* pointer to buffer to transmit */    FAST int            bufLen,         /* length of buffer */    FAST int            flags           /* flags to underlying protocols */    )    {    FAST struct socket 	*so;    FAST int		status;    FAST int		spl;    int			len;		/* value/result */    struct uio		usrIo;		/* user IO structure */    struct iovec	ioVec;		/* IO vector structure */    struct mbuf *	pMbuf = NULL;	/* pointer to mbuf */    struct uio *	pUsrIo = NULL;	/* pointer to User IO structure */    /* extract the socket from the fd */    if ((so = (struct socket *) iosFdValue (s)) == (struct socket *) ERROR)	{	if ((flags & MSG_MBUF) && (buf))	    m_freem ((struct mbuf *)buf);        return (ERROR);	}    spl = splnet ();    if (flags & MSG_MBUF)	{	pMbuf = (struct mbuf *) buf; 	len = bufLen;	}    else	{	usrIo.uio_iov = &ioVec;	usrIo.uio_iovcnt = 1;	usrIo.uio_offset = 0;	usrIo.uio_resid = bufLen;	usrIo.uio_segflg = UIO_USERSPACE;	usrIo.uio_rw = UIO_WRITE;	ioVec.iov_base = (caddr_t) buf;	ioVec.iov_len = bufLen;	pUsrIo = &usrIo;	len = usrIo.uio_resid;	}    status = sosend (so, (struct mbuf *) NULL,  pUsrIo, pMbuf,		     (struct mbuf *)NULL, flags);    splx (spl);    if (status)        {        if (pUsrIo != NULL && pUsrIo->uio_resid != len &&            (status == EINTR || status == EWOULDBLOCK))            status = OK;        }    return (status == OK ? ((pUsrIo == NULL) ? len : (len - pUsrIo->uio_resid))	    : ERROR);    }/********************************************************************************* bsdSockWrite - write to a socket** This routine is called by the I/O system when a write is done on a socket.*/LOCAL int bsdSockWrite    (    FAST struct socket  *so,    FAST char           *buf,    FAST int            bufLen    )    {    FAST int		status;    FAST int		spl;    int			len;		/* value/result */    struct uio		usrIo;		/* user IO structure */    struct iovec	ioVec;		/* IO vector structure */    spl = splnet ();    usrIo.uio_iov = &ioVec;    usrIo.uio_iovcnt = 1;    usrIo.uio_offset = 0;    usrIo.uio_resid = bufLen;    usrIo.uio_segflg = UIO_USERSPACE;    usrIo.uio_rw = UIO_WRITE;    ioVec.iov_base = (caddr_t) buf;    ioVec.iov_len = bufLen;    len = usrIo.uio_resid;    status = sosend (so, (struct mbuf *) NULL,  &usrIo, (struct mbuf *)0,		     (struct mbuf *)NULL, 0);    splx (spl);    if (status)        {        if (usrIo.uio_resid != len &&            (status == EINTR || status == EWOULDBLOCK))            status = OK;        }    return (status == OK ? (len - usrIo.uio_resid)  : ERROR);    }/********************************************************************************* bsdSendmsg - send a message to a socket** This routine sends a message to a datagram socket.  It may be used in * place of sendto() to decrease the overhead of reconstructing the * message-header structure (`msghdr') for each message.* * RETURNS* The number of bytes sent, or ERROR if the call fails.** NOMANUAL*/int sendmsg    (    int                 sd,     /* socket to send to */    struct msghdr       *mp,    /* scatter-gather message header */    int                 flags   /* flags to underlying protocols */    )    {    FAST struct iovec 	*iov;    FAST struct iovec   * pIovCopy; /* kernel copy of user iov */    FAST int 		ix;    struct socket 	*so;    struct uio 		auio;    struct iovec        aiov [UIO_SMALLIOV];  /* use stack for small user iov */    struct mbuf		*to;    struct mbuf		*control;    int 		len;    int 		status;    int 		slev;    BOOL                mallocedIov;    /* TRUE if kernel iov copy malloced */                                        /* from system pool */    int                 sendLen;        /* length of sent message */    if (flags & MSG_MBUF)	{        netErrnoSet (EINVAL);        return (ERROR);			/* mbuf uio not supported */	}    /* extract the socket from the fd */    if ((so = (struct socket *) iosFdValue (sd)) == (struct socket *) ERROR)        return (ERROR);    /* allocate space to copy user struct iovec */    if (mp->msg_iovlen >= UIO_SMALLIOV)	{	if (mp->msg_iovlen >= UIO_MAXIOV)	    {	    netErrnoSet (EMSGSIZE);	    return (ERROR);	    }	MALLOC (pIovCopy, struct iovec *, 		sizeof (struct iovec) * mp->msg_iovlen, MT_DATA, M_WAIT);	if (pIovCopy == NULL)	    {	    netErrnoSet (ENOBUFS);	    return (ERROR);	    }	mallocedIov = TRUE;	}    else	{	pIovCopy = aiov;	mallocedIov = FALSE;	}    slev = splnet ();    auio.uio_iov 	= pIovCopy;    auio.uio_iovcnt 	= mp->msg_iovlen;    auio.uio_segflg 	= UIO_USERSPACE;    auio.uio_offset 	= 0;    auio.uio_rw 	= UIO_WRITE;    auio.uio_resid 	= 0;    iov 		= mp->msg_iov;    for (ix = 0; ix < mp->msg_iovlen; ix++, iov++)        {        if (iov->iov_len < 0)            {            netErrnoSet (EINVAL);	    splx (slev);	    if (mallocedIov)		{		FREE (auio.uio_iov, MT_IOV);		}            return (ERROR);            }        if (iov->iov_len == 0)            continue;	pIovCopy->iov_len = iov->iov_len;	pIovCopy->iov_base = iov->iov_base;	pIovCopy++;        auio.uio_resid += iov->iov_len;        }    /* Save a pointer to struct iovec copy */    pIovCopy = auio.uio_iov;    if (mp->msg_name)        {        status = bsdSockargs (&to, mp->msg_name, mp->msg_namelen, MT_SONAME);        if (status)	    {	    netErrnoSet (status);	    splx (slev);	    if (mallocedIov)		{		FREE (pIovCopy, MT_DATA);		}            return (ERROR);	    }        }    else        to = 0;    if (mp->msg_control)        {        status = bsdSockargs (&control, mp->msg_control, mp->msg_controllen,                          MT_CONTROL);        if (status)	    {	    if (to)		m_freem(to);	    netErrnoSet (status);	    splx (slev);	    if (mallocedIov)		{		FREE (pIovCopy, MT_DATA);		}	    return (ERROR);	    }        }    else        control = 0;    len = auio.uio_resid;    status = sosend (so, to, &auio, (struct mbuf *)0, control, flags);

⌨️ 快捷键说明

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