VirtualBox

Changeset 98073 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Jan 13, 2023 11:24:01 AM (2 years ago)
Author:
vboxsync
Message:

Main/HostHardwareLinux.cpp: We don't need to dynamically resolve inotify functions, we can assume we're on a Linux verion that has it and is more than recent enough for inotify_init1 and pipe2 (see also dns monitoring code).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/linux/HostHardwareLinux.cpp

    r96407 r98073  
    5656#ifdef VBOX_USB_WITH_SYSFS
    5757# ifdef VBOX_USB_WITH_INOTIFY
    58 #  include <dlfcn.h>
    59 #  include <fcntl.h>
     58#  include <fcntl.h>        /* O_CLOEXEC */
    6059#  include <poll.h>
    6160#  include <signal.h>
    6261#  include <unistd.h>
     62#  include <sys/inotify.h>
    6363# endif
    6464#endif
    6565
    66 #include <vector>
     66//#include <vector>
    6767
    6868#include <errno.h>
     
    116116
    117117
    118 /** Find the length of a string, ignoring trailing non-ascii or control
     118/**
     119 * Find the length of a string, ignoring trailing non-ascii or control
    119120 * characters
    120  * @note Code duplicated in HostHardwareFreeBSD.cpp  */
     121 *
     122 * @note Code duplicated in HostHardwareFreeBSD.cpp
     123 */
    121124static size_t strLenStripped(const char *pcsz) RT_NOTHROW_DEF
    122125{
     
    131134/**
    132135 * Get the name of a floppy drive according to the Linux floppy driver.
     136 *
    133137 * @returns true on success, false if the name was not available (i.e. the
    134138 *          device was not readable, or the file name wasn't a PC floppy
     
    159163/**
    160164 * Create a UDI and a description for a floppy drive based on a number and the
    161  * driver's name for it.  We deliberately return an ugly sequence of
    162  * characters as the description rather than an English language string to
    163  * avoid translation issues.
     165 * driver's name for it.
     166 *
     167 * We deliberately return an ugly sequence of characters as the description
     168 * rather than an English language string to avoid translation issues.
    164169 *
    165170 * @returns true if we know the device to be valid, false otherwise
     
    350355 * Initialise the device strings (description and UDI) for a DVD drive based on
    351356 * vendor and model name strings.
     357 *
    352358 * @param pcszVendor  the vendor ID string
    353359 * @param pcszModel   the product ID string
     
    10181024typedef struct inotifyWatch
    10191025{
    1020     /** Pointer to the inotify_add_watch() glibc function/Linux API */
    1021     int (*inotify_add_watch)(int, const char *, uint32_t);
    10221026    /** The native handle of the inotify fd. */
    10231027    int mhInotify;
     
    10261030/** The flags we pass to inotify - modify, create, delete, change permissions
    10271031 */
    1028 #define IN_FLAGS 0x306
     1032#define MY_IN_FLAGS (IN_CREATE | IN_DELETE | IN_MODIFY | IN_ATTRIB)
     1033AssertCompile(MY_IN_FLAGS == 0x306);
    10291034
    10301035static int iwAddWatch(inotifyWatch *pSelf, const char *pcszPath)
    10311036{
    10321037    errno = 0;
    1033     if (  pSelf->inotify_add_watch(pSelf->mhInotify, pcszPath, IN_FLAGS) >= 0
    1034         || (errno == EACCES))
     1038    if (   inotify_add_watch(pSelf->mhInotify, pcszPath, MY_IN_FLAGS) >= 0
     1039        || errno == EACCES)
    10351040        return VINF_SUCCESS;
    10361041    /* Other errors listed in the manpage can be treated as fatal */
     
    10411046static int iwInit(inotifyWatch *pSelf)
    10421047{
    1043     int (*inotify_init)(void);
    1044     int fd, flags;
    1045     int rc = VINF_SUCCESS;
    1046 
    10471048    AssertPtr(pSelf);
    10481049    pSelf->mhInotify = -1;
    1049     errno = 0;
    1050     *(void **)(&inotify_init) = dlsym(RTLD_DEFAULT, "inotify_init");
    1051     if (!inotify_init)
    1052         return VERR_LDR_IMPORTED_SYMBOL_NOT_FOUND;
    1053     *(void **)(&pSelf->inotify_add_watch)
    1054                     = dlsym(RTLD_DEFAULT, "inotify_add_watch");
    1055     if (!pSelf->inotify_add_watch)
    1056         return VERR_LDR_IMPORTED_SYMBOL_NOT_FOUND;
    1057     fd = inotify_init();
    1058     if (fd < 0)
    1059     {
    1060         Assert(errno > 0);
    1061         return RTErrConvertFromErrno(errno);
    1062     }
    1063     Assert(errno == 0);
    1064 
    1065     flags = fcntl(fd, F_GETFL, NULL);
    1066     if (   flags < 0
    1067         || fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0
    1068         || fcntl(fd, F_SETFD, FD_CLOEXEC) < 0 /* race here */)
    1069     {
    1070         Assert(errno > 0);
    1071         rc = RTErrConvertFromErrno(errno);
    1072     }
    1073     if (RT_FAILURE(rc))
    1074         close(fd);
    1075     else
    1076     {
    1077         Assert(errno == 0);
     1050    int fd = inotify_init1(IN_CLOEXEC | IN_NONBLOCK);
     1051    if (fd >= 0)
     1052    {
    10781053        pSelf->mhInotify = fd;
    1079     }
    1080     return rc;
     1054        return VINF_SUCCESS;
     1055    }
     1056    Assert(errno > 0);
     1057    return RTErrConvertFromErrno(errno);
    10811058}
    10821059
     
    11471124    /** Is inotify available and working on this system?  If so we expect that
    11481125     * this implementation will be usable. */
    1149     /** @todo test the "inotify in glibc but not in the kernel" case. */
    11501126    static bool Available(void)
    11511127    {
    1152         int (*inotify_init)(void);
    1153 
    1154         *(void **)(&inotify_init) = dlsym(RTLD_DEFAULT, "inotify_init");
    1155         if (!inotify_init)
    1156             return false;
    1157         int fd = inotify_init();
    1158         if (fd == -1)
    1159             return false;
    1160         close(fd);
    1161         return true;
     1128        int const fd = inotify_init1(IN_CLOEXEC | IN_NONBLOCK);
     1129        if (fd >= 0)
     1130            close(fd);
     1131        return fd >= 0;
    11621132    }
    11631133
     
    11811151    /*
    11821152     * Create the pipe and set the close-on-exec flag.
     1153     * ASSUMES we're building and running on Linux 2.6.27 or later (pipe2).
    11831154     */
    11841155    int aFds[2] = {-1, -1};
    1185     if (pipe(aFds))
     1156    if (pipe2(aFds, O_CLOEXEC))
    11861157        return RTErrConvertFromErrno(errno);
    1187     if (   fcntl(aFds[0], F_SETFD, FD_CLOEXEC) < 0
    1188         || fcntl(aFds[1], F_SETFD, FD_CLOEXEC) < 0)
    1189     {
    1190         int rc = RTErrConvertFromErrno(errno);
    1191         close(aFds[0]);
    1192         close(aFds[1]);
    1193         return rc;
    1194     }
    11951158
    11961159    *phPipeRead  = aFds[0];
     
    12041167}
    12051168
    1206 hotplugInotifyImpl::hotplugInotifyImpl(const char *pcszDevicesRoot) :
    1207     mhWakeupPipeR(-1), mhWakeupPipeW(-1), mfWaiting(0),
    1208     mpcszDevicesRoot(pcszDevicesRoot), mStatus(VERR_WRONG_ORDER)
     1169hotplugInotifyImpl::hotplugInotifyImpl(const char *pcszDevicesRoot)
     1170    : mhWakeupPipeR(-1), mhWakeupPipeW(-1), mfWaiting(0)
     1171    , mpcszDevicesRoot(pcszDevicesRoot), mStatus(VERR_WRONG_ORDER)
    12091172{
    12101173#  ifdef DEBUG
     
    12171180     * available */
    12181181#  endif
    1219     int rc;
    1220     do {
    1221         if (RT_FAILURE(rc = iwInit(&mWatches)))
    1222             break;
    1223         if (RT_FAILURE(rc = iwAddWatch(&mWatches, mpcszDevicesRoot)))
    1224             break;
    1225         if (RT_FAILURE(rc = pipeCreateSimple(&mhWakeupPipeR, &mhWakeupPipeW)))
    1226             break;
    1227     } while (0);
     1182
     1183    int rc = iwInit(&mWatches);
     1184    if (RT_SUCCESS(rc))
     1185    {
     1186        rc = iwAddWatch(&mWatches, mpcszDevicesRoot);
     1187        if (RT_SUCCESS(rc))
     1188            rc = pipeCreateSimple(&mhWakeupPipeR, &mhWakeupPipeW);
     1189    }
    12281190    mStatus = rc;
    12291191    if (RT_FAILURE(rc))
     
    12551217    AssertRCReturn(mStatus, VERR_WRONG_ORDER);
    12561218    errno = 0;
    1257     do {
     1219    do
    12581220        cchRead = read(iwGetFD(&mWatches), chBuf, sizeof(chBuf));
    1259     } while (cchRead > 0);
     1221    while (cchRead > 0);
    12601222    if (cchRead == 0)
    12611223        return VINF_SUCCESS;
     
    12861248{
    12871249    int rc;
    1288     char **ppszEntry;
    1289     VECTOR_PTR(char *) vecpchDevs;
    12901250
    12911251    AssertRCReturn(mStatus, VERR_WRONG_ORDER);
    12921252    bool fEntered = ASMAtomicCmpXchgU32(&mfWaiting, 1, 0);
    12931253    AssertReturn(fEntered, VERR_WRONG_ORDER);
     1254
     1255    VECTOR_PTR(char *) vecpchDevs;
    12941256    VEC_INIT_PTR(&vecpchDevs, char *, RTStrFree);
    1295     do {
    1296         struct pollfd pollFD[MAX_POLLID];
    1297 
     1257    for (;;)
     1258    {
    12981259        rc = readFilePaths(mpcszDevicesRoot, &vecpchDevs, false);
    12991260        if (RT_SUCCESS(rc))
     1261        {
     1262            char **ppszEntry;
    13001263            VEC_FOR_EACH(&vecpchDevs, char *, ppszEntry)
    13011264                if (RT_FAILURE(rc = iwAddWatch(&mWatches, *ppszEntry)))
    13021265                    break;
     1266        }
    13031267        if (RT_FAILURE(rc))
    13041268            break;
     1269
     1270        struct pollfd pollFD[MAX_POLLID];
    13051271        pollFD[RPIPE_ID].fd = mhWakeupPipeR;
    13061272        pollFD[RPIPE_ID].events = POLLIN;
     
    13321298        if (RT_FAILURE(rc = drainInotify()))
    13331299            break;
    1334     } while (false);
     1300    }
     1301
    13351302    mfWaiting = 0;
    13361303    VEC_CLEANUP_PTR(&vecpchDevs);
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