VirtualBox

Changeset 5126 in vbox


Ignore:
Timestamp:
Oct 1, 2007 2:52:32 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
24987
Message:

Solaris

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/err.h

    r5113 r5126  
    966966 * have any init or term programs. */
    967967#define VERR_HOSTIF_FD_AND_INIT_TERM                (-3104)
     968/** The Host Interface Networking terminate program failed. */
     969#define VERR_HOSTIF_TERM_FAILED                     (-3105)
    968970/** @} */
    969971
  • trunk/src/VBox/Devices/Builtins.cpp

    r4642 r5126  
    191191        return rc;
    192192#endif
    193 #if defined(RT_OS_L4) || defined(RT_OS_LINUX) || defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
     193#if defined(RT_OS_L4) || defined(RT_OS_LINUX) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS)
    194194    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostInterface);
    195195    if (VBOX_FAILURE(rc))
  • trunk/src/VBox/Devices/Makefile.kmk

    r5076 r5126  
    449449        Storage/DrvHost% \
    450450        , $(Drivers_SOURCES))
    451 Drivers_SOURCES.os2   =
     451Drivers_SOURCES.solaris = \
     452    Network/DrvTAP.cpp
    452453endif
    453454
  • trunk/src/VBox/Devices/Network/DrvTAP.cpp

    r5013 r5126  
    2222*******************************************************************************/
    2323#define LOG_GROUP LOG_GROUP_DRV_TUN
     24#include <VBox/log.h>
    2425#include <VBox/pdmdrv.h>
    2526
     
    2728#include <iprt/file.h>
    2829#include <iprt/string.h>
     30#include <iprt/path.h>
    2931#ifdef ASYNC_NET
    3032# include <iprt/thread.h>
     
    3638#include <sys/poll.h>
    3739#ifdef RT_OS_SOLARIS
     40# include <sys/stat.h>
     41# include <sys/ethernet.h>
     42# include <sys/sockio.h>
     43# include <netinet/in.h>
     44# include <netinet/in_systm.h>
     45# include <netinet/ip.h>
     46# include <netinet/ip_icmp.h>
     47# include <netinet/udp.h>
     48# include <netinet/tcp.h>
     49# include <net/if.h>
     50# include <stropts.h>
    3851# include <fcntl.h>
     52# include <ctype.h>
     53# include <stdlib.h>
    3954#else
    4055# include <sys/fcntl.h>
     
    7590    /** TAP device file handle. */
    7691    RTFILE                  FileDevice;
     92    /** The configured TAP device name. */
     93    char                   *pszDeviceName;
     94#ifdef RT_OS_SOLARIS
     95    /** The actual TAP device name. */
     96    char                   *pszDeviceNameActual;
     97#endif
     98    /** TAP setup application. */
     99    char                   *pszSetupApplication;
     100    /** TAP terminate application. */
     101    char                   *pszTerminateApplication;
    77102#ifdef ASYNC_NET
    78103    /** The write end of the control pipe. */
     
    119144/** Converts a pointer to TAP::INetworkConnector to a PRDVTAP. */
    120145#define PDMINETWORKCONNECTOR_2_DRVTAP(pInterface) ( (PDRVTAP)((uintptr_t)pInterface - RT_OFFSETOF(DRVTAP, INetworkConnector)) )
     146
     147
     148/*******************************************************************************
     149*   Internal Functions                                                         *
     150*******************************************************************************/
     151#ifdef RT_OS_SOLARIS
     152static DECLCALLBACK(int) SolarisTAPAttach(PPDMDRVINS pDrvIns);
     153#endif
    121154
    122155
     
    415448
    416449
     450#if defined(RT_OS_SOLARIS)
     451/**
     452 * Calls OS-specific TAP setup application/script.
     453 *
     454 * @returns VBox error code.
     455 * @param   pData           The instance data.
     456 */
     457static int drvTAPSetupApplication(PDRVTAP pData)
     458{
     459    char *pszArgs[3];
     460    pszArgs[0] = pData->pszSetupApplication;
     461    pszArgs[1] = pData->pszDeviceNameActual;
     462    pszArgs[2] = NULL;
     463
     464/** @todo use RTProcCreate */
     465
     466    Log2(("Starting TAP setup application: %s %s\n", pData->pszSetupApplication, pData->pszDeviceNameActual));
     467    pid_t pid = fork();
     468    if (pid < 0)
     469    {
     470        /* Bad. fork() failed! */
     471        LogRel(("TAP#%d: Failed to fork() process for running TAP setup application: %s\n", pDrvIns->iInstance,
     472              pData->pszSetupApplication, strerror(errno)));
     473        return VERR_HOSTIF_INIT_FAILED;
     474    }
     475    if (pid == 0)
     476    {
     477        /* Child process. */
     478        execv(pszArgs[0], pszArgs);
     479        _exit(1);
     480    }
     481
     482    /* Parent process. */
     483    int result;
     484    while (waitpid(pid, &result, 0) < 0)
     485        ;
     486    if (!WIFEXITED(result) || WEXITSTATUS(result) != 0)
     487    {
     488        LogRel(("TAP#%d: Failed to run TAP setup application: %s\n", pDrvIns->iInstance, pData->pszSetupApplication));
     489        return VERR_HOSTIF_INIT_FAILED;
     490    }
     491   
     492    return VINF_SUCCESS;
     493}
     494
     495
     496/**
     497 * Calls OS-specific TAP terminate application/script.
     498 *
     499 * @returns VBox error code.
     500 * @param   pData           The instance data.
     501 */
     502static int drvTAPTerminateApplication(PDRVTAP pData)
     503{
     504    char *pszArgs[3];
     505    pszArgs[0] = pData->pszTerminateApplication;
     506    pszArgs[1] = pData->pszDeviceNameActual;
     507    pszArgs[2] = NULL;
     508
     509/** @todo use RTProcCreate */
     510
     511    Log2(("Starting TAP terminate application: %s %s\n", pData->pszTerminateApplication, pData->pszDeviceNameActual));
     512    pid_t pid = fork();
     513    if (pid < 0)
     514    {
     515        /* Bad. fork() failed! */
     516        LogRel(("TAP#%d: Failed to fork() process for running TAP terminate application: %s\n", pDrvIns->iInstance,
     517              pData->pszTerminateApplication, strerror(errno)));
     518        return VERR_HOSTIF_TERM_FAILED;
     519    }
     520    if (pid == 0)
     521    {
     522        /* Child process. */
     523        execv(pszArgs[0], pszArgs);
     524        _exit(1);
     525    }
     526       
     527    /* Parent process. */
     528    int result;
     529    while (waitpid(pid, &result, 0) < 0)
     530        ;
     531    if (!WIFEXITED(result) || WEXITSTATUS(result) != 0)
     532    {
     533        LogRel(("TAP#%d: Failed to run TAP terminate application: %s\n", pDrvIns->iInstance, pData->pszSetupApplication));
     534        return VERR_HOSTIF_TERM_FAILED;
     535    }
     536   
     537    return VINF_SUCCESS;
     538}
     539
     540#endif /* RT_OS_SOLARIS */
     541
     542
     543#ifdef RT_OS_SOLARIS
     544/** From net/if_tun.h, installed by Universal TUN/TAP driver */
     545# define TUNNEWPPA                   (('T'<<16) | 0x0001)
     546/** Whether to enable ARP for TAP. */
     547# define VBOX_SOLARIS_TAP_ARP        1
     548
     549/**
     550 * Creates/Attaches TAP device to IP.
     551 *
     552 * @returns VBox error code.
     553 * @param   pDrvIns          The driver instance data.
     554 * @param   pszDevName       Pointer to device name.
     555 */
     556static DECLCALLBACK(int) SolarisTAPAttach(PPDMDRVINS pDrvIns)
     557{
     558    PDRVTAP pData = PDMINS2DATA(pDrvIns, PDRVTAP);
     559    LogFlow(("SolarisTapAttach: pData=%p\n", pData));
     560   
     561   
     562    /* Close previously opened file desc., if any. */
     563    static int s_IPFileDes = -1; /** @todo r=bird: what's the point of keeping this open? */
     564    if (s_IPFileDes >= 0)
     565        close(s_IPFileDes);
     566   
     567    s_IPFileDes = open("/dev/udp", O_RDWR, 0);
     568    if (s_IPFileDes < 0)
     569        return PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
     570                                   N_("Failed to open /dev/udp. errno=%d"), errno);
     571   
     572    int TapFileDes = open("/dev/tap", O_RDWR, 0);
     573    if (TapFileDes < 0)
     574        return PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
     575                                   N_("Failed to open /dev/tap for TAP. errno=%d"), errno);
     576   
     577    /* Use the PPA from the ifname if possible (e.g "tap2", then use 2 as PPA) */
     578    int iPPA = -1;
     579    if (pData->pszDeviceName)
     580    {
     581        size_t cch = strlen(pData->pszDeviceName);
     582        if (cch > 1 && isdigit(pData->pszDeviceName[cch - 1]) != 0)
     583            iPPA = pData->pszDeviceName[cch - 1] - '0';
     584    }
     585   
     586    struct strioctl ioIF;
     587    ioIF.ic_cmd = TUNNEWPPA;
     588    ioIF.ic_len = sizeof(iPPA);
     589    ioIF.ic_dp = (char *)(&iPPA);
     590    ioIF.ic_timout = 0;
     591    iPPA = ioctl(TapFileDes, I_STR, &ioIF);
     592    if (iPPA < 0) /** @todo r=bird: leaving at least one file descriptor open. */
     593        return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
     594                                   N_("Failed to get new interface. errno=%d"), errno);
     595   
     596    int InterfaceFD = open("/dev/tap", O_RDWR, 0);
     597    if (!InterfaceFD)
     598        return PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_HIF_OPEN_FAILED, RT_SRC_POS,
     599                                   N_("Failed to open interface /dev/tap. errno=%d"), errno);
     600   
     601    if (ioctl(InterfaceFD, I_PUSH, "ip") == -1)
     602    {
     603        close(InterfaceFD);
     604        return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
     605                                   N_("Failed to push IP. errno=%d"), errno);
     606    }
     607   
     608    struct lifreq ifReq;
     609    memset(&ifReq, 0, sizeof(ifReq));
     610    if (ioctl(InterfaceFD, SIOCGLIFFLAGS, &ifReq) == -1)
     611        LogRel(("TAP#%d: Failed to get interface flags.\n", pDrvIns->iInstance));
     612
     613    char szTmp[16];
     614    char *pszDevName = pData->pszDeviceName;   
     615    if (!pData->pszDeviceName || !*pData->pszDeviceName)
     616    {
     617        RTStrPrintf(szTmp, sizeof(szTmp), "tap%d", iPPA);
     618        pszDevName = szTmp;
     619    }
     620   
     621    ifReq.lifr_ppa = iPPA;
     622    RTStrPrintf (ifReq.lifr_name, sizeof(ifReq.lifr_name), pszDevName);
     623   
     624    if (ioctl(InterfaceFD, SIOCSLIFNAME, &ifReq) == -1)
     625        LogRel(("TAP#%d: Failed to set PPA. errno=%d\n", pDrvIns->iInstance, errno));
     626   
     627    if (ioctl(InterfaceFD, SIOCGLIFFLAGS, &ifReq) == -1)
     628        LogRel(("TAP#%d: Failed to get interface flags after setting PPA. errno=%d\n", pDrvIns->iInstance, errno));
     629
     630#ifdef VBOX_SOLARIS_TAP_ARP
     631    /* Interface */
     632    if (ioctl(InterfaceFD, I_PUSH, "arp") == -1)
     633        LogRel(("TAP#%d: Failed to push ARP to Interface FD. errno=%d\n", pDrvIns->iInstance, errno));
     634
     635    /* IP */
     636    if (ioctl(s_IPFileDes, I_POP, NULL) == -1)
     637        LogRel(("TAP#%d: Failed I_POP from IP FD. errno=%d\n", pDrvIns->iInstance, errno));
     638
     639    if (ioctl(s_IPFileDes, I_PUSH, "arp") == -1)
     640        LogRel(("TAP#%d: Failed to push ARP to IP FD. errno=%d\n", pDrvIns->iInstance, errno));
     641   
     642    /* ARP */
     643    int ARPFileDes = open("/dev/tap", O_RDWR, 0);
     644    if (ARPFileDes < 0)
     645        LogRel(("TAP#%d: Failed to open for /dev/tap for ARP. errno=%d", pDrvIns->iInstance, errno));
     646   
     647    if (ioctl(ARPFileDes, I_PUSH, "arp") == -1)
     648        LogRel(("TAP#%d: Failed to push ARP to ARP FD. errno=%d\n", pDrvIns->iInstance, errno));
     649   
     650    ioIF.ic_cmd = SIOCSLIFNAME;
     651    ioIF.ic_timout = 0;
     652    ioIF.ic_len = sizeof(ifReq);
     653    ioIF.ic_dp = (char *)&ifReq;
     654    if (ioctl(ARPFileDes, I_STR, &ioIF) == -1)
     655        LogRel(("TAP#%d: Failed to set interface name to ARP.\n", pDrvIns->iInstance));
     656#endif
     657
     658    /* We must use I_LINK and not I_PLINK as I_PLINK makes the link persistent.
     659     * Then we would not be able unlink the interface if we reuse it.
     660     * Even 'unplumb' won't work after that.
     661     */
     662    int IPMuxID = ioctl(s_IPFileDes, I_LINK, InterfaceFD);
     663    if (IPMuxID == -1)
     664    {
     665        close(InterfaceFD);
     666#ifdef VBOX_SOLARIS_TAP_ARP
     667        close(ARPFileDes);
     668#endif
     669        LogRel(("TAP#%d: Cannot link TAP device to IP.\n", pDrvIns->iInstance));
     670        return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
     671                    N_("Failed to link TAP device to IP. Check TAP interface name. errno=%d"), errno);
     672    }
     673   
     674#ifdef VBOX_SOLARIS_TAP_ARP
     675    int ARPMuxID = ioctl(s_IPFileDes, I_LINK, ARPFileDes);
     676    if (ARPMuxID == -1)
     677        LogRel(("TAP#%d: Failed to link TAP device to ARP\n", pDrvIns->iInstance));
     678   
     679    close(ARPFileDes);
     680#endif
     681    close(InterfaceFD);
     682
     683    /* Reuse ifReq */
     684    memset(&ifReq, 0, sizeof(ifReq));
     685    RTStrPrintf (ifReq.lifr_name, sizeof(ifReq.lifr_name), pszDevName);
     686    ifReq.lifr_ip_muxid  = IPMuxID;
     687#ifdef VBOX_SOLARIS_TAP_ARP
     688    ifReq.lifr_arp_muxid = ARPMuxID;
     689#endif
     690
     691    if (ioctl(s_IPFileDes, SIOCSLIFMUXID, &ifReq) == -1)
     692    {
     693#ifdef VBOX_SOLARIS_TAP_ARP
     694        ioctl(IPFileDes, I_PUNLINK, ARPMuxID);
     695#endif
     696        ioctl(IPFileDes, I_PUNLINK, IPMuxID);
     697        close(s_IPFileDes);
     698        s_IPFileDes = -1;
     699        LogRel(("TAP#%d: Failed to set Mux ID.\n", pDrvIns->iInstance));
     700        return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_IOCTL, RT_SRC_POS,
     701                                   N_("Failed to set Mux ID. Check TAP interface name. errno=%d"), errno);
     702    }
     703
     704    /* what's the point? */
     705    pData->FileDevice = (RTFILE)TapFileDes;
     706    pData->pszDeviceNameActual = RTStrDup(pszDevName);
     707   
     708    return VINF_SUCCESS;
     709}
     710
     711#endif  /* RT_OS_SOLARIS */
     712
     713
    417714/**
    418715 * Queries an interface to the driver.
     
    451748{
    452749    LogFlow(("drvTAPDestruct\n"));
     750    PDRVTAP pData = PDMINS2DATA(pDrvIns, PDRVTAP);
     751
    453752#ifdef ASYNC_NET
    454     PDRVTAP pData = PDMINS2DATA(pDrvIns, PDRVTAP);
    455 
    456753    /*
    457754     * Terminate the Async I/O Thread.
     
    487784    }
    488785#endif
     786
     787#ifdef RT_OS_SOLARIS
     788    if (pData->pszTerminateApplication)
     789        drvTAPTerminateApplication(pData);
     790
     791    RTStrFree(pData->pszDeviceNameActual);
     792#endif
     793    MMR3HeapFree(pData->pszDeviceName);
     794    MMR3HeapFree(pData->pszSetupApplication);
     795    MMR3HeapFree(pData->pszTerminateApplication);
    489796}
    490797
     
    509816    pData->pDrvIns                      = pDrvIns;
    510817    pData->FileDevice                   = NIL_RTFILE;
     818    pData->pszDeviceName                = NULL;
     819#ifdef RT_OS_SOLARIS
     820    pData->pszDeviceNameActual          = NULL;
     821#endif
     822    pData->pszSetupApplication          = NULL;
     823    pData->pszTerminateApplication      = NULL;
    511824#ifdef ASYNC_NET
    512825    pData->Thread                       = NIL_RTTHREAD;
     
    524837     * Validate the config.
    525838     */
    526     if (!CFGMR3AreValuesValid(pCfgHandle, "Device\0InitProg\0TermProg\0FileHandle\0"))
     839    if (!CFGMR3AreValuesValid(pCfgHandle, "Device\0InitProg\0TermProg\0FileHandle\0TAPSetupApplication\0TAPTerminateApplication"))
    527840        return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES, "");
    528841
     
    546859     * Read the configuration.
    547860     */
     861#if defined(RT_OS_SOLARIS)   /** @todo Other platforms' TAP code should be moved here from ConsoleImpl & VBoxBFE. */
     862    rc = CFGMR3QueryStringAlloc(pCfgHandle, "TAPSetupApplication", &pData->pszSetupApplication);
     863    if (VBOX_SUCCESS(rc))
     864    {
     865        if (!RTPathExists(pData->pszSetupApplication))
     866            return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
     867                                       N_("Invalid TAP setup program path: %s"), pData->pszSetupApplication);
     868    }
     869    else if (rc != VERR_CFGM_VALUE_NOT_FOUND)
     870        return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Configuration error: failed to query \"TAPTerminateApplication\""));
     871
     872    rc = CFGMR3QueryStringAlloc(pCfgHandle, "TAPTerminateApplication", &pData->pszTerminateApplication);
     873    if (VBOX_SUCCESS(rc))
     874    {
     875        if (!RTPathExists(pData->pszTerminateApplication))
     876            return PDMDrvHlpVMSetError(pDrvIns, VERR_HOSTIF_INIT_FAILED, RT_SRC_POS,
     877                                       N_("Invalid TAP terminate program path: %s"), pData->pszTerminateApplication);
     878    }
     879    else if (rc != VERR_CFGM_VALUE_NOT_FOUND)
     880        return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Configuration error: failed to query \"TAPTerminateApplication\""));
     881
     882   
     883    rc = CFGMR3QueryStringAlloc(pCfgHandle, "Device", &pData->pszDeviceName);
     884    if (VBOX_FAILURE(rc))
     885        return PDMDRV_SET_ERROR(pDrvIns, rc,
     886                                N_("Configuration error: Query for \"Device\" string failed!"));
     887
     888    /*
     889     * Do the setup.
     890     */
     891    rc = SolarisTAPAttach(pDrvIns);
     892    if (VBOX_FAILURE(rc))
     893        return rc;
     894
     895    if (pData->pszSetupApplication)
     896    {
     897        rc = drvTAPSetupApplication(pData);
     898        if (RT_SUCCESS(rc))
     899            return rc;
     900    }
     901
     902#else /* !SOLARIS */
     903
    548904    int32_t iFile;
    549905    rc = CFGMR3QueryS32(pCfgHandle, "FileHandle", &iFile);
     
    555911        return PDMDrvHlpVMSetError(pDrvIns, VERR_INVALID_HANDLE, RT_SRC_POS,
    556912                                   N_("The TAP file handle %RTfile is not valid!"), pData->FileDevice);
     913#endif /* !SOLARIS */
    557914
    558915    /*
  • trunk/src/VBox/Devices/Storage/DrvHostBase.cpp

    r4071 r5126  
    4040# include <sys/ioctl.h>
    4141# include <sys/fcntl.h>
     42# include <errno.h>
     43
     44#elif defined(RT_OS_SOLARIS)
     45# include <fcntl.h>
    4246# include <errno.h>
    4347
  • trunk/src/VBox/Frontends/VBoxBFE/VBoxBFE.cpp

    r5014 r5126  
    16591659                    rc = CFGMR3InsertInteger(pCfg, "FileHandle", (RTFILE)tapFD);                    UPDATE_RC();
    16601660
     1661#elif defined(RT_OS_SOLARIS)
     1662                    rc = CFGMR3InsertString(pCfg, "Device", g_aNetDevs[ulInstance].pszName); UPDATE_RC();
     1663
    16611664#elif defined(RT_OS_OS2)
    16621665                    /*
     
    16791682
    16801683
    1681 #else /* !RT_OS_LINUX && !RT_OS_L4 */
     1684#else
    16821685                    FatalError("Name based HIF devices not implemented yet for this host platform\n");
    16831686                    return VERR_NOT_IMPLEMENTED;
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r5119 r5126  
    52295229        int rcVBox = VERR_NOT_IMPLEMENTED;
    52305230#elif defined(RT_OS_SOLARIS)
    5231         /** @todo Implemented tap networking for Solaris. */
    5232         int rcVBox = VERR_NOT_IMPLEMENTED;
     5231        /* nothing to do */
     5232        int rcVBox = VINF_SUCCESS;
    52335233#elif defined(VBOX_WITH_UNIXY_TAP_NETWORKING)
    52345234# error "PORTME: Implement OS specific TAP interface open/creation."
  • trunk/src/VBox/Main/ConsoleImpl2.cpp

    r5101 r5126  
    949949                        rc = CFGMR3InsertString(pLunL0, "Driver", "HostInterface"); RC_CHECK();
    950950                        rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg);             RC_CHECK();
     951# if defined(RT_OS_SOLARIS)
     952                        /* Device name/number is required for Solaris as we need it for TAP PPA. */
     953                        Bstr tapDeviceName;
     954                        networkAdapter->COMGETTER(HostInterface)(tapDeviceName.asOutParam());
     955                        if (!tapDeviceName.isEmpty())
     956                            rc = CFGMR3InsertString(pCfg, "Device", Utf8Str(tapDeviceName)); RC_CHECK();
     957
     958                        /* TAP setup application/script */
     959                        Bstr tapSetupApp;
     960                        networkAdapter->COMGETTER(TAPSetupApplication)(tapSetupApp.asOutParam());
     961                        if (!tapSetupApp.isEmpty())
     962                            rc = CFGMR3InsertString(pCfg, "TAPSetupApplication", Utf8Str(tapSetupApp)); RC_CHECK();
     963                       
     964                        /* TAP terminate application/script */
     965                        Bstr tapTerminateApp;
     966                        networkAdapter->COMGETTER(TAPTerminateApplication)(tapTerminateApp.asOutParam());
     967                        if (!tapTerminateApp.isEmpty())
     968                            rc = CFGMR3InsertString(pCfg, "TAPTerminateApplication", Utf8Str(tapTerminateApp)); RC_CHECK();
     969                       
     970                        /* "FileHandle" must NOT be inserted here, it is done in DrvTAP.cpp */
     971
     972# else
    951973                        rc = CFGMR3InsertInteger(pCfg, "FileHandle", pConsole->maTapFD[ulInstance]); RC_CHECK();
     974# endif
    952975                    }
    953976#elif defined(RT_OS_WINDOWS)
Note: See TracChangeset for help on using the changeset viewer.

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