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

📄 bsdsocklib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    )    {    struct mbuf *nam;    int namelen = *addrlen;    int slev;    FAST struct socket *so;    FAST int fd;#ifndef  _WRS_VXWORKS_5_X    OBJ_ID fdObject;    STATUS status;#endif    /* extract the socket from the fd */    if ((so = (struct socket *) iosFdValue (s)) == (struct socket *) ERROR)        return (ERROR);#ifdef VIRTUAL_STACK    if (stackInstFromSockVsidSet (s) != OK)        return (ERROR);#endif    /* VIRTUAL_STACK */    slev = splnet ();    if ((so->so_options & SO_ACCEPTCONN) == 0)        {        netErrnoSet (EINVAL);        splx (slev);        return (ERROR);        }    if ((so->so_state & SS_NBIO) && so->so_qlen == 0)        {        netErrnoSet (EWOULDBLOCK);        splx(slev);        return (ERROR);        }    while (so->so_qlen == 0 && so->so_error == 0)        {        if (so->so_state & SS_CANTRCVMORE)            {            so->so_error = ECONNABORTED;            break;            }        ksleep (so->so_timeoSem);        }    if (so->so_error)        {        netErrnoSet ((int) so->so_error);        so->so_error = 0;        splx (slev);        return (ERROR);        }    if ( (nam = mBufClGet (M_WAIT, MT_SONAME, CL_SIZE_128, TRUE)) == NULL)	{	netErrnoSet (ENOBUFS);	splx (slev);	return (ERROR);	}    {    struct socket *aso = so->so_q;    if (soqremque(aso, 1) == 0)	panic ("accept");    so = aso;    }    (void) soaccept (so, nam);    if (addr)        {        if (namelen > nam->m_len)            namelen = nam->m_len;        /* XXX SHOULD COPY OUT A CHAIN HERE */        (void) copyout (mtod(nam, caddr_t), (caddr_t)addr,			namelen);        (void) copyout ((caddr_t)&namelen, (caddr_t)addrlen,			sizeof (*addrlen));        if (bsdSock43ApiFlag)            {            /* Convert the address structure contents to the BSD 4.3 format. */            bsdSockAddrRevert (addr);            }        }    m_freem (nam);    splx (slev);    /* put the new socket into an fd */    if ((fd = iosFdNew ((DEV_HDR *) &bsdSockDev, bsdSockName, (int) so)) ==	ERROR)	{	(void)bsdSockClose (so);	return (ERROR);	}#ifndef _WRS_VXWORKS_5_X        /* set ownership of socket semaphores */        fdObject = iosFdObjIdGet (fd);    if (fdObject == NULL)        {        (void)bsdSockClose (so);        return (ERROR);        }    status = objOwnerSet (so->so_timeoSem, fdObject);    if (status == ERROR)        {        (void)bsdSockClose (so);        return (ERROR);        }    status = objOwnerSet (so->so_rcv.sb_Sem, fdObject);    if (status == ERROR)        {        (void)bsdSockClose (so);        return (ERROR);        }    status = objOwnerSet (so->so_snd.sb_Sem, fdObject);    if (status == ERROR)        {        (void)bsdSockClose (so);        return (ERROR);        }#endif /*  _WRS_VXWORKS_5_X */        /* save fd in the socket structure */    so->so_fd = fd;#ifdef VIRTUAL_STACK        /* set the vsid in the socket to the current stack */    if (setsockopt (fd, SOL_SOCKET, SO_VSID,                            (char *)&myStackNum, sizeof (myStackNum)) != OK)        {        (void)bsdSockClose (so);        return (ERROR);        }#endif    /* VIRTUAL_STACK */        return (fd);    }/********************************************************************************* bsdConnect - initiate a connection to a socket** If <s> is a socket of type SOCK_STREAM, this routine establishes a virtual* circuit between <s> and another socket specified by <name>.  If <s> is of* type SOCK_DGRAM, it permanently specifies the peer to which messages* are sent.  If <s> is of type SOCK_RAW, it specifies the raw socket upon* which data is to be sent and received.  The <name> parameter specifies the* address of the other socket.** RETURNS* OK, or ERROR if the call fails.** NOMANUAL*/STATUS connect    (    int s,                      /* socket descriptor */    struct sockaddr *name,      /* addr of socket to connect */    int namelen                 /* length of name, in bytes */    )    {    struct mbuf *nam;    int slev;    int status;    FAST struct socket *so;    /* extract the socket from the fd */    if ((so = (struct socket *) iosFdValue (s)) == (struct socket *) ERROR)        return (ERROR);#ifdef VIRTUAL_STACK    if (stackInstFromSockVsidSet (s) != OK)        return (ERROR);#endif    /* VIRTUAL_STACK */    /*     * For non-blocking sockets, exit immediately if a previous connection     * attempt is still pending.     */    slev = splnet ();    if ((so->so_state & SS_NBIO) &&	(so->so_state & SS_ISCONNECTING)) {        splx (slev);	netErrnoSet (EALREADY);	return (ERROR);	}    splx (slev);    status = bsdSockargs (&nam, (caddr_t)name, namelen, MT_SONAME);    if (status)	{	netErrnoSet (status);        return (ERROR);	}#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    /*     * Attempt to establish the connection. For TCP sockets, this routine     * just begins the three-way handshake process. For all other sockets,     * it succeeds or fails immediately.     */    status = soconnect (so, nam);    if (status)	{        /*         * Fatal error: unable to record remote address or (TCP only)         * couldn't send initial SYN segment.         */	netErrnoSet (status);	so->so_state &= ~SS_ISCONNECTING;	m_freem(nam);	return (ERROR);	}    /*     * For non-blocking sockets, exit if the connection attempt is     * still pending. This condition only occurs for TCP sockets if     * no SYN reply arrives before the soconnect() routine completes.     */    slev = splnet();    if ((so->so_state & SS_NBIO) &&        (so->so_state & SS_ISCONNECTING))        {        netErrnoSet (EINPROGRESS);	splx (slev);	m_freem (nam);        return (ERROR);        }    /*     * Wait until a pending connection completes or a timeout occurs.     * This delay might occur for TCP sockets. Other socket types     * "connect" or fail instantly.     */    while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)        ksleep (so->so_timeoSem);    if (so->so_error)	{        /* Connection attempt failed immediately or (TCP only) timed out. */        status = ERROR;	netErrnoSet ((int) so->so_error);	so->so_error = 0;	}    else        {        /* Connection attempt succeeded. */        status = OK;        }    splx (slev);    m_freem (nam);    return (status);    }/******************************************************************************** bsdConnectWithTimeout - attempt socket connection within 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 before timeout** 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 		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);#ifdef VIRTUAL_STACK    if (stackInstFromSockVsidSet (sock) != OK)        return (ERROR);#endif    /* VIRTUAL_STACK */        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 a TCP socket is set to non-blocking mode, the connect()          * routine might return EINPROGRESS (if the three-way handshake         * is not completed immediately) or EALREADY (if a previous connect         * attempt is still pending). All other errors (for any socket type)         * indicate a fatal problem, such as insufficient memory to record         * the remote address or (for TCP) an inability to transmit the         * initial SYN segment.	 */        error = errnoGet () & 0xffff;	if (error == EINPROGRESS || error == EALREADY)            {	    /*             * Use the select() routine to monitor the socket status. The             * socket will be writable when the three-way handshake completes             * or when the handshake timeout occurs.	     */	    FD_ZERO (&writeFds);	    FD_SET (sock, &writeFds);	    if (select (FD_SETSIZE, (fd_set *) NULL, &writeFds,			(fd_set *) NULL, timeVal) > 0)		{		/* The FD_ISSET test is theoretically redundant, but safer. */		if (FD_ISSET (sock, &writeFds))		    {		    /*                     * The connection attempt has completed. The getpeername()                     * routine retrieves the remote address if the three-way                     * handshake succeeded and fails if the attempt timed out.		     */		    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);	}#ifdef VIRTUAL_STACK    if (stackInstFromSockVsidSet (s) != OK)        return (ERROR);#endif    /* VIRTUAL_STACK */    spl = splnet ();    status = bsdSockargs (&mto, (char *) to, tolen, MT_SONAME);    if (status)	{	netErrnoSet (status);	if ((flags & MSG_MBUF) && (buf))	    m_freem ((struct mbuf *)buf);

⌨️ 快捷键说明

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