VirtualBox

Ignore:
Timestamp:
Aug 25, 2022 2:27:54 AM (2 years ago)
Author:
vboxsync
Message:

IPRT: Resolve SetHandleInformation and GetHandleInformation dynamically and let the affected code deal with it specifically. Refactored the rtSocketCreate function to combine with setting inheritance, so we can use the WSA_FLAG_NO_HANDLE_INHERIT when available to avoid explicitly setting inheritance. Made RTSocketSetInheritance check the status before trying to set it, returning VERR_NET_NOT_UNSUPPORTED if tool old windows version. Also made GetVersionExW go via a function pointer since it wasn't there in NT 3.1. bugref:10261

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/socket.cpp

    r96407 r96475  
    572572 * @param   iType               The socket type (SOCK_XXX).
    573573 * @param   iProtocol           Socket parameter, usually 0.
    574  */
    575 DECLHIDDEN(int) rtSocketCreate(PRTSOCKET phSocket, int iDomain, int iType, int iProtocol)
     574 * @param   fInheritable        Set to true if the socket should be inherted by
     575 *                              child processes, false if not inheritable.
     576 */
     577DECLHIDDEN(int) rtSocketCreate(PRTSOCKET phSocket, int iDomain, int iType, int iProtocol, bool fInheritable)
    576578{
    577579#ifdef RT_OS_WINDOWS
     
    587589    /*
    588590     * Create the socket.
    589      */
    590 #ifdef RT_OS_WINDOWS
    591     RTSOCKETNATIVE hNative = g_pfnsocket(iDomain, iType, iProtocol);
     591     *
     592     * The RTSocketSetInheritance operation isn't necessarily reliable on windows,
     593     * so try use WSA_FLAG_NO_HANDLE_INHERIT with WSASocketW when possible.
     594     */
     595#ifdef RT_OS_WINDOWS
     596    bool           fCallSetInheritance = true;
     597    RTSOCKETNATIVE hNative;
     598    if (g_pfnWSASocketW)
     599    {
     600        DWORD fWsaFlags = WSA_FLAG_OVERLAPPED | (!fInheritable ? WSA_FLAG_NO_HANDLE_INHERIT : 0);
     601        hNative = g_pfnWSASocketW(iDomain, iType, iProtocol, NULL, 0 /*Group*/, fWsaFlags);
     602        if (hNative != NIL_RTSOCKETNATIVE)
     603            fCallSetInheritance = false;
     604        else
     605        {
     606            if (!fInheritable)
     607                hNative = g_pfnsocket(iDomain, iType, iProtocol);
     608            if (hNative == NIL_RTSOCKETNATIVE)
     609                return rtSocketError();
     610        }
     611    }
     612    else
     613    {
     614        hNative = g_pfnsocket(iDomain, iType, iProtocol);
     615        if (hNative == NIL_RTSOCKETNATIVE)
     616            return rtSocketError();
     617    }
    592618#else
    593619    RTSOCKETNATIVE hNative = socket(iDomain, iType, iProtocol);
    594 #endif
    595620    if (hNative == NIL_RTSOCKETNATIVE)
    596621        return rtSocketError();
     622#endif
    597623
    598624    /*
     
    600626     */
    601627    int rc = rtSocketCreateForNative(phSocket, hNative, false /*fLeaveOpen*/);
    602     if (RT_FAILURE(rc))
     628    if (RT_SUCCESS(rc))
     629    {
     630#ifdef RT_OS_WINDOWS
     631        if (fCallSetInheritance)
     632#endif
     633            RTSocketSetInheritance(*phSocket, fInheritable);
     634    }
     635    else
    603636    {
    604637#ifdef RT_OS_WINDOWS
     
    943976    AssertReturn(RTMemPoolRefCount(pThis) >= (pThis->cUsers ? 2U : 1U), VERR_CALLER_NO_REFERENCE);
    944977
    945     int rc = VINF_SUCCESS;
    946 #ifdef RT_OS_WINDOWS
    947     if (!SetHandleInformation((HANDLE)pThis->hNative, HANDLE_FLAG_INHERIT, fInheritable ? HANDLE_FLAG_INHERIT : 0))
    948         rc = RTErrConvertFromWin32(GetLastError());
     978#ifndef RT_OS_WINDOWS
     979    if (fcntl(pThis->hNative, F_SETFD, fInheritable ? 0 : FD_CLOEXEC) < 0)
     980        return RTErrConvertFromErrno(errno);
     981    return VINF_SUCCESS;
    949982#else
    950     if (fcntl(pThis->hNative, F_SETFD, fInheritable ? 0 : FD_CLOEXEC) < 0)
    951         rc = RTErrConvertFromErrno(errno);
    952 #endif
    953 
    954     return rc;
     983    /* Windows is more complicated as sockets are complicated wrt inheritance
     984       (see stackoverflow for details).  In general, though we cannot hope to
     985       make a socket really non-inheritable before vista as other layers in
     986       the winsock maze may have additional handles associated with the socket. */
     987    if (g_pfnGetHandleInformation)
     988    {
     989        /* Check if the handle is already in what seems to be the right state
     990           before we try doing anything. */
     991        DWORD fFlags;
     992        if (g_pfnGetHandleInformation((HANDLE)pThis->hNative, &fFlags))
     993        {
     994            if (RT_BOOL(fFlags & HANDLE_FLAG_INHERIT) == fInheritable)
     995                return VINF_SUCCESS;
     996        }
     997    }
     998
     999    if (!g_pfnSetHandleInformation)
     1000        return VERR_NET_NOT_UNSUPPORTED;
     1001
     1002    if (!g_pfnSetHandleInformation((HANDLE)pThis->hNative, HANDLE_FLAG_INHERIT, fInheritable ? HANDLE_FLAG_INHERIT : 0))
     1003        return RTErrConvertFromWin32(GetLastError());
     1004    /** @todo Need we do something related to WS_SIO_ASSOCIATE_HANDLE or
     1005     *        WS_SIO_TRANSLATE_HANDLE? Or what  other handles could be associated
     1006     *        with the socket? that we need to modify? */
     1007
     1008    return VINF_SUCCESS;
     1009#endif
    9551010}
    9561011
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette