dlls/ws2_32/socket.c
/***********************************************************************
 *              WS2_send                (INTERNAL)
 *
 * Workhorse for both synchronous and asynchronous send() operations.
 */
WS2_send                (INTERNAL)
Workhorse for both synchronous and asynchronous send() operations.
WS2_send ( INTERNAL ) Workhorse for both synchronous and asynchronous send () operations .
static int WS2_send( int fd, struct ws2_async *wsa )
{
    struct msghdr hdr;
    union generic_unix_sockaddr unix_addr;
    int n, ret;
    hdr.msg_name = NULL;
    hdr.msg_namelen = 0;
    if (wsa->addr)
    {
        hdr.msg_name = &unix_addr;
        hdr.msg_namelen = ws_sockaddr_ws2u( wsa->addr, wsa->addrlen.val, &unix_addr );
        if ( !hdr.msg_namelen )
        {
            errno = EFAULT;
            return -1;
        }
#if defined(HAS_IPX) && defined(SOL_IPX)
        if(wsa->addr->sa_family == WS_AF_IPX)
        {
            struct sockaddr_ipx* uipx = (struct sockaddr_ipx*)hdr.msg_name;
            int val=0;
            socklen_t len = sizeof(int);
            if(getsockopt(fd, SOL_IPX, IPX_TYPE, &val, &len) != -1)
                uipx->sipx_type = val;
        }
#endif
    }
    hdr.msg_iov = wsa->iovec + wsa->first_iovec;
    hdr.msg_iovlen = wsa->n_iovecs - wsa->first_iovec;
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
    hdr.msg_accrights = NULL;
    hdr.msg_accrightslen = 0;
#else
    hdr.msg_control = NULL;
    hdr.msg_controllen = 0;
    hdr.msg_flags = 0;
#endif
    ret = sendmsg(fd, &hdr, wsa->flags);
    if (ret >= 0)
    {
        n = ret;
        while (wsa->first_iovec < wsa->n_iovecs && wsa->iovec[wsa->first_iovec].iov_len <= n)
            n -= wsa->iovec[wsa->first_iovec++].iov_len;
        if (wsa->first_iovec < wsa->n_iovecs)
        {
            wsa->iovec[wsa->first_iovec].iov_base = (char*)wsa->iovec[wsa->first_iovec].iov_base + n;
            wsa->iovec[wsa->first_iovec].iov_len -= n;
        }
    }
    return ret;
}
static int WS2_send ( int fd , struct ws2_async * wsa ) { struct msghdr hdr ; union generic_unix_sockaddr unix_addr ; int n , ret ; hdr . msg_name = NULL ; hdr . msg_namelen = 0 ; if ( wsa -> addr ) { hdr . msg_name = & unix_addr ; hdr . msg_namelen = ws_sockaddr_ws2u ( wsa -> addr , wsa -> addrlen . val , & unix_addr ) ; if ( ! hdr . msg_namelen ) { errno = EFAULT ; return -1 ; } #if defined ( HAS_IPX ) && defined ( SOL_IPX ) if ( wsa -> addr -> sa_family == WS_AF_IPX ) { struct sockaddr_ipx * uipx = ( struct sockaddr_ipx * ) hdr . msg_name ; int val = 0 ; socklen_t len = sizeof ( int ) ; if ( getsockopt ( fd , SOL_IPX , IPX_TYPE , & val , & len ) != -1 ) uipx -> sipx_type = val ; } #endif } hdr . msg_iov = wsa -> iovec + wsa -> first_iovec ; hdr . msg_iovlen = wsa -> n_iovecs - wsa -> first_iovec ; #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS hdr . msg_accrights = NULL ; hdr . msg_accrightslen = 0 ; #else hdr . msg_control = NULL ; hdr . msg_controllen = 0 ; hdr . msg_flags = 0 ; #endif ret = sendmsg ( fd , & hdr , wsa -> flags ) ; if ( ret >= 0 ) { n = ret ; while ( wsa -> first_iovec < wsa -> n_iovecs && wsa -> iovec [ wsa -> first_iovec ] . iov_len <= n ) n -= wsa -> iovec [ wsa -> first_iovec ++ ] . iov_len ; if ( wsa -> first_iovec < wsa -> n_iovecs ) { wsa -> iovec [ wsa -> first_iovec ] . iov_base = ( char * ) wsa -> iovec [ wsa -> first_iovec ] . iov_base + n ; wsa -> iovec [ wsa -> first_iovec ] . iov_len -= n ; } } return ret ; }
WS2_send                (INTERNAL)
 Workhorse for both synchronous and asynchronous send() operations.
WS2_send ( INTERNAL ) Workhorse for both synchronous and asynchronous send () operations .
/* The packet type is stored at the ipx socket level; At least the linux kernel seems
             *  to do something with it in case hdr.msg_name is NULL. Nonetheless can we use it to store
             *  the packet type and then we can retrieve it using getsockopt. After that we can set the
             *  ipx type in the sockaddr_opx structure with the stored value.
             */