VirtualBox

Changeset 32258 in vbox for trunk


Ignore:
Timestamp:
Sep 6, 2010 8:33:08 PM (14 years ago)
Author:
vboxsync
Message:

Main/USB/linux: simplified the vector container and the code using it

Location:
trunk/src/VBox/Main
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/HostHardwareLinux.h

    r32142 r32258  
    2525#include <iprt/cpp/ministring.h>
    2626#include <vector>
     27#include <vector.h>
    2728
    2829/**
     
    118119     * method. */
    119120    char *mSysfsPath;
    120     /** List of interfaces.  Only one simulaneous traversal is possible. */
    121     struct USBInterfaceList *mInterfaces;
     121    /** List of interfaces as sysfs paths */
     122    VECTOR_PTR(char *) mvecpszInterfaces;
    122123} USBDeviceInfo;
    123124
     
    130131
    131132/**
    132  * Return the first in a list of USB device interfaces (that is, its sysfs
    133  * path), or NULL if there are none.
    134  */
    135 char *USBDevInfoFirstInterface(struct USBInterfaceList *pInterfaces);
    136 
    137 /**
    138  * Return the next in a list of USB device interfaces (that is, its sysfs
    139  * path), or NULL if there are none.
    140  */
    141 char *USBDevInfoNextInterface(struct USBInterfaceList *pInterfaces);
    142 
    143 
    144 /** Vector type holding device information */
    145 #define VECTOR_TYPE       USBDeviceInfo
    146 #define VECTOR_TYPENAME   USBDeviceInfoList
    147 #define VECTOR_DESTRUCTOR USBDevInfoCleanup
    148 #include "vector.h"
    149 
    150 
    151 /**
    152133 * Class for probing and returning information about host USB devices.
    153134 * To use this class, create an instance, call the update methods to do the
     
    157138{
    158139    /** The list of currently available USB devices */
    159     USBDeviceInfoList mDeviceList;
     140    VECTOR_OBJ(USBDeviceInfo) mvecDevInfo;
    160141} VBoxMainUSBDeviceInfo;
    161142
     
    163144static inline int VBoxMainUSBDevInfoInit(VBoxMainUSBDeviceInfo *pSelf)
    164145{
    165     return USBDeviceInfoList_init(&pSelf->mDeviceList);
     146    return VEC_INIT_OBJ(&pSelf->mvecDevInfo, USBDeviceInfo, USBDevInfoCleanup);
    166147}
    167148
     
    169150static inline void VBoxMainUSBDevInfoCleanup(VBoxMainUSBDeviceInfo *pSelf)
    170151{
    171     USBDeviceInfoList_cleanup(&pSelf->mDeviceList);
     152    VEC_CLEANUP_OBJ(&pSelf->mvecDevInfo);
    172153}
    173154
     
    178159 */
    179160int USBDevInfoUpdateDevices(VBoxMainUSBDeviceInfo *pSelf);
    180 
    181 /** Get the first element in the list of USB devices. */
    182 static inline const USBDeviceInfoList_iterator *USBDevInfoBegin
    183                 (VBoxMainUSBDeviceInfo *pSelf)
    184 {
    185     return USBDeviceInfoList_begin(&pSelf->mDeviceList);
    186 }
    187 
    188 
    189 /** Get the last element in the list of USB devices. */
    190 static inline const USBDeviceInfoList_iterator *USBDevInfoEnd
    191                 (VBoxMainUSBDeviceInfo *pSelf)
    192 {
    193     return USBDeviceInfoList_end(&pSelf->mDeviceList);
    194 }
    195161
    196162
  • trunk/src/VBox/Main/include/vector.h

    r32114 r32258  
    11/** @file
    2  * STL-like vector implementation in C
     2 * STL-inspired vector implementation in C
    33 * @note  functions in this file are inline to prevent warnings about
    44 *        unused static functions.  I assume that in this day and age a
    55 *        compiler makes its own decisions about whether to actually
    66 *        inline a function.
     7 * @note  as this header is included in rdesktop-vrdp, we do not include other
     8 *        required header files here (to wit assert.h, err.h, mem.h and
     9 *        types.h).  These must be included first.  If this moves to iprt, we
     10 *        should write a wrapper around it doing that.
     11 * @todo  can we do more of the type checking at compile time somehow?
    712 */
    813
     
    1924 */
    2025
    21 #define VECTOR_CONCAT(a, b) a ## b
    22 #define VECTOR_XCONCAT(a, b) VECTOR_CONCAT(a, b)
    23 /** A publicly visible (method, type, etc) name relating to the vector type */
    24 #define VECTOR_PUBLIC(NAME) VECTOR_XCONCAT(VECTOR_TYPENAME, _ ## NAME)
    25 /** An implementation-private (method, type, etc) name */
    26 #define VECTOR_INTERNAL(NAME) VECTOR_XCONCAT(VECTOR_TYPENAME, _internal_ ## NAME)
    27 /** The size of a vector element */
    28 #define VECTOR_ELEMENT_SIZE sizeof(VECTOR_TYPE)
     26#ifndef MAIN_VECTOR_H
     27# define MAIN_VECTOR_H
     28
     29/*** Helper macros and deinitions ***/
     30
    2931/** The unit by which the vector capacity is increased */
    3032#define VECTOR_ALLOC_UNIT 16
    3133
    32 #ifndef VECTOR_TYPE
    33 /** VECTOR_TYPE must be defined to the type that the vector will contain.  The
    34  * macro will be undef-ed again by this header. */
    35 # error You must define VECTOR_TYPE before including this header!
    36 #endif
    37 #ifndef VECTOR_TYPENAME
    38 /** VECTOR_TYPENAME must be defined to the typename for the vector.  The
    39  * macro will be undef-ed again by this header. */
    40 # error You must define VECTOR_TYPENAME before including this header!
    41 #endif
    42 #ifndef VECTOR_ALLOCATOR
    43 /** VECTOR_ALLOCATOR can be defined to an alternative allocator for the
    44  * vector's memory.  The allocator must be a function with realloc semantics.
    45  * The macro will be undef-ed again by this header. */
    46 # define VECTOR_ALLOCATOR RTMemRealloc
    47 #endif
    48 #ifndef VECTOR_DESTRUCTOR
    49 /** VECTOR_DESTRUCTOR can be defined to be a routine to clean up vector
    50  * elements before they are freed.  It must return void and take a pointer to
    51  * an element as a parameter.  The macro will be undef-ed again by this header.
    52  */
    53 # define VECTOR_DESTRUCTOR VECTOR_INTERNAL(empty_destructor)
    54 #endif
    55 
    56 /** Structure describing the vector itself */
    57 typedef struct VECTOR_TYPENAME
    58 {
    59     /** The beginning of the allocated memory */
    60     VECTOR_TYPE *mBegin;
    61     /** Pointer to just after the end of the last element */
    62     VECTOR_TYPE *mEnd;
    63     /** Pointer to just after the end of the allocated memory */
    64     VECTOR_TYPE *mCapacity;
    65 } VECTOR_TYPENAME;
    66 
    67 /** Non-constant iterator over the vector */
    68 typedef VECTOR_TYPE *VECTOR_PUBLIC(iterator);
    69 
    70 /*** Private methods ***/
    71 
    72 /** Destructor that does nothing. */
    73 static inline void VECTOR_INTERNAL(empty_destructor)(VECTOR_TYPENAME *pSelf)
    74 {
    75     (void) pSelf;
     34/** Calculate a hash of a string of tokens for sanity type checking */
     35#define VECTOR_TOKEN_HASH(token) \
     36    ((unsigned) \
     37     (  VECTOR_TOKEN_HASH4(token, 0) \
     38      ^ VECTOR_TOKEN_HASH4(token, 4) \
     39      ^ VECTOR_TOKEN_HASH4(token, 8) \
     40      ^ VECTOR_TOKEN_HASH4(token, 12)))
     41
     42/** Helper macro for @a VECTOR_TOKEN_HASH */
     43#define VECTOR_TOKEN_HASH_VALUE(token, place, mul) \
     44    (sizeof(#token) > place ? #token[place] * mul : 0)
     45
     46/** Helper macro for @a VECTOR_TOKEN_HASH */
     47#define VECTOR_TOKEN_HASH4(token, place) \
     48      VECTOR_TOKEN_HASH_VALUE(token, place,     0x1) \
     49    ^ VECTOR_TOKEN_HASH_VALUE(token, place + 1, 0x100) \
     50    ^ VECTOR_TOKEN_HASH_VALUE(token, place + 2, 0x10000) \
     51    ^ VECTOR_TOKEN_HASH_VALUE(token, place + 3, 0x1000000)
     52
     53/** Generic vector structure, used by @a VECTOR_OBJ and @a VECTOR_PTR */
     54#define VECTOR_STRUCT \
     55{ \
     56    /** The number of elements in the vector */ \
     57    size_t mcElements; \
     58    /** The current capacity of the vector */ \
     59    size_t mcCapacity; \
     60    /** The size of an element */ \
     61    size_t mcbElement; \
     62    /** Hash value of the element type */ \
     63    unsigned muTypeHash; \
     64    /** The elements themselves */ \
     65    void *mpvaElements; \
     66    /** Destructor for elements - takes a pointer to an element. */ \
     67    void (*mpfnCleanup)(void *); \
     68}
     69
     70/*** Structure definitions ***/
     71
     72/** A vector of values or objects */
     73typedef struct VECTOR_OBJ VECTOR_STRUCT VECTOR_OBJ;
     74
     75/** A vector of pointer values.  (A handy special case.) */
     76typedef struct VECTOR_PTR VECTOR_STRUCT VECTOR_PTR;
     77
     78/** Convenience macro for annotating the type of the vector.  Unfortunately the
     79 * type name is only cosmetic. */
     80/** @todo can we do something useful with the type? */
     81#define VECTOR_OBJ(type) VECTOR_OBJ
     82
     83/** Convenience macro for annotating the type of the vector.  Unfortunately the
     84 * type name is only cosmetic. */
     85#define VECTOR_PTR(type) VECTOR_PTR
     86
     87/*** Private helper functions and macros ***/
     88
     89#define VEC_GET_ELEMENT_OBJ(pvaElements, cbElement, cElement) \
     90    ((void *)((char *)(pvaElements) + (cElement) * (cbElement)))
     91
     92#define VEC_GET_ELEMENT_PTR(pvaElements, cElement) \
     93    (*(void **)VEC_GET_ELEMENT_OBJ(pvaElements, sizeof(void *), cElement))
     94
     95/** Default cleanup function that does nothing. */
     96DECLINLINE(void) vecNoCleanup(void *pvElement)
     97{
     98    (void) pvElement;
     99}
     100
     101/** Expand an existing vector, implementation */
     102DECLINLINE(int) vecExpand(size_t *pcCapacity, void **ppvaElements,
     103                            size_t cbElement)
     104{
     105    size_t cOldCap, cNewCap;
     106    void *pRealloc;
     107
     108    cOldCap = *pcCapacity;
     109    cNewCap = cOldCap + VECTOR_ALLOC_UNIT;
     110    pRealloc = RTMemRealloc(*ppvaElements, cNewCap * cbElement);
     111    if (!pRealloc)
     112        return VERR_NO_MEMORY;
     113    *pcCapacity = cNewCap;
     114    *ppvaElements = pRealloc;
     115    return VINF_SUCCESS;
    76116}
    77117
    78118/** Expand an existing vector */
    79 static inline int VECTOR_INTERNAL(expand)(VECTOR_TYPENAME *pSelf)
    80 {
    81     size_t cNewCap = pSelf->mCapacity - pSelf->mBegin + VECTOR_ALLOC_UNIT;
    82     size_t cOffEnd = pSelf->mEnd - pSelf->mBegin;
    83     void *pRealloc = VECTOR_ALLOCATOR(pSelf->mBegin,
    84                                       cNewCap * VECTOR_ELEMENT_SIZE);
    85     if (!pRealloc)
    86         return 0;
    87     pSelf->mBegin = (VECTOR_TYPE *)pRealloc;
    88     pSelf->mEnd = pSelf->mBegin + cOffEnd;
    89     pSelf->mCapacity = pSelf->mBegin + cNewCap;
    90     memset(pSelf->mEnd, 0, pSelf->mCapacity - pSelf->mEnd);
    91     return 1;
    92 }
    93 
    94 /** Expand an existing vector */
    95 static inline void VECTOR_INTERNAL(destruct_all)(VECTOR_TYPENAME *pSelf)
    96 {
    97     VECTOR_TYPE *pIter;
    98     for (pIter = pSelf->mBegin; pIter < pSelf->mEnd; ++pIter)
    99         VECTOR_DESTRUCTOR(pIter);
    100 }
    101 
    102 /*** Public methods ***/
    103 
    104 /** Initialise a newly allocated vector.  The vector will be zeroed on failure.
    105  */
    106 static inline int VECTOR_PUBLIC(init)(VECTOR_TYPENAME *pSelf)
    107 {
    108     memset(pSelf, 0, sizeof(*pSelf));
    109     return VECTOR_INTERNAL(expand)(pSelf);
    110 }
    111 
    112 /** Clean up a vector so that the memory can be returned.  For convenience,
    113  * this may be used safely on a zeroed vector structure. */
    114 static inline void VECTOR_PUBLIC(cleanup)(VECTOR_TYPENAME *pSelf)
    115 {
    116     if (pSelf->mBegin)
    117     {
    118         VECTOR_INTERNAL(destruct_all)(pSelf);
    119         VECTOR_ALLOCATOR(pSelf->mBegin, 0);
    120     }
    121     pSelf->mBegin = pSelf->mEnd = pSelf->mCapacity = NULL;
    122 }
    123 
    124 /** Add a value onto the end of a vector */
    125 static inline int VECTOR_PUBLIC(push_back)(VECTOR_TYPENAME *pSelf,
    126                                     VECTOR_TYPE *pElement)
    127 {
    128     if (pSelf->mEnd == pSelf->mCapacity && !VECTOR_INTERNAL(expand)(pSelf))
    129         return 0;
    130     if (pElement)
    131         *pSelf->mEnd = *pElement;
    132     ++pSelf->mEnd;
    133     return 1;
    134 }
    135 
    136 /** Reset the vector */
    137 static inline void VECTOR_PUBLIC(clear)(VECTOR_TYPENAME *pSelf)
    138 {
    139     VECTOR_INTERNAL(destruct_all)(pSelf);
    140     memset(pSelf->mBegin, 0, pSelf->mEnd - pSelf->mBegin);
    141     pSelf->mEnd = pSelf->mBegin;
    142 }
    143 
    144 /** Number of elements in the vector */
    145 static inline size_t VECTOR_PUBLIC(size)(VECTOR_TYPENAME *pSelf)
    146 {
    147     return (pSelf->mEnd - pSelf->mBegin) / VECTOR_ELEMENT_SIZE;
    148 }
    149 
    150 /** Get the special "begin" iterator for a vector */
    151 static inline const VECTOR_PUBLIC(iterator) *VECTOR_PUBLIC(begin)
    152                                                  (VECTOR_TYPENAME *pSelf)
    153 {
    154     return &pSelf->mBegin;
    155 }
    156 
    157 /** Get the special "end" iterator for a vector */
    158 static inline const VECTOR_PUBLIC(iterator) *VECTOR_PUBLIC(end)
    159                                                  (VECTOR_TYPENAME *pSelf)
    160 {
    161     return &pSelf->mEnd;
    162 }
    163 
    164 /** A structure with pointers to class operations to save too much use of long
    165  * identifiers in source code.  Use like:
    166  *   <vector_type>_op_table *pOps = &<vector_type>_ops;
    167  * and then
    168  *   pOps->init(&my_vector);
    169  */
    170 typedef const struct VECTOR_INTERNAL(op_table)
    171 {
    172     int    (*init)      (VECTOR_TYPENAME *pSelf);
    173     void   (*cleanup)   (VECTOR_TYPENAME *pSelf);
    174     int    (*push_back) (VECTOR_TYPENAME *pSelf, VECTOR_TYPE *pElement);
    175     void   (*clear)     (VECTOR_TYPENAME *pSelf);
    176     size_t (*size)      (VECTOR_TYPENAME *pSelf);
    177     const VECTOR_PUBLIC(iterator) *
    178            (*begin)     (VECTOR_TYPENAME *pSelf);
    179     const VECTOR_PUBLIC(iterator) *
    180            (*end)       (VECTOR_TYPENAME *pSelf);
    181 } VECTOR_PUBLIC(op_table);
    182 
    183 static VECTOR_PUBLIC(op_table) VECTOR_PUBLIC(ops) =
    184 {
    185     VECTOR_PUBLIC(init),
    186     VECTOR_PUBLIC(cleanup),
    187     VECTOR_PUBLIC(push_back),
    188     VECTOR_PUBLIC(clear),
    189     VECTOR_PUBLIC(size),
    190     VECTOR_PUBLIC(begin),
    191     VECTOR_PUBLIC(end)
    192 };
    193 
    194 /*** Iterator methods ***/
    195 
    196 /** Initialise a newly allocated iterator */
    197 static inline void VECTOR_PUBLIC(iter_init)(VECTOR_PUBLIC(iterator) *pSelf,
    198                                      const VECTOR_PUBLIC(iterator) *pOther)
    199 {
    200     *pSelf = *pOther;
    201 }
    202 
    203 /** Dereference an iterator */
    204 static inline VECTOR_TYPE *VECTOR_PUBLIC(iter_target)(VECTOR_PUBLIC(iterator) *pSelf)
    205 {
    206     return *pSelf;
    207 }
    208 
    209 /** Increment an iterator */
    210 static inline void VECTOR_PUBLIC(iter_incr)(VECTOR_PUBLIC(iterator) *pSelf)
    211 {
    212     ++*pSelf;
    213 }
    214 
    215 /** Test whether an iterator is less than another. */
    216 static inline int VECTOR_PUBLIC(iter_lt)(const VECTOR_PUBLIC(iterator) *pFirst,
    217                                          const VECTOR_PUBLIC(iterator) *pSecond)
    218 {
    219     return *pFirst < *pSecond;
    220 }
    221 
    222 /** Test whether an iterator is equal to another.  The special values
    223  * ITERATOR_BEGIN and ITERATOR_END are recognised. */
    224 static inline int VECTOR_PUBLIC(iter_eq)(const VECTOR_PUBLIC(iterator) *pFirst,
    225                                          const VECTOR_PUBLIC(iterator) *pSecond)
    226 {
    227     return *pFirst == *pSecond;
    228 }
    229 
    230 /** A structure with pointers to iterator operations to save too much use of
    231  * long identifiers in source code.  Use like:
    232  *   <vector_type>_iter_op_table *pOps = &<vector_type>_iter_ops;
    233  * and then
    234  *   pOps->init(&my_iter, &other_iter);
    235  */
    236 typedef const struct VECTOR_INTERNAL(iter_op_table)
    237 {
    238     void         (*init)    (VECTOR_PUBLIC(iterator) *pSelf,
    239                              const VECTOR_PUBLIC(iterator) *pOther);
    240     VECTOR_TYPE *(*target)  (VECTOR_PUBLIC(iterator) *pSelf);
    241     void         (*incr)    (VECTOR_PUBLIC(iterator) *pSelf);
    242     int          (*lt) (const VECTOR_PUBLIC(iterator) *pFirst,
    243                              const VECTOR_PUBLIC(iterator) *pSecond);
    244     int          (*eq) (const VECTOR_PUBLIC(iterator) *pFirst,
    245                              const VECTOR_PUBLIC(iterator) *pSecond);
    246 } VECTOR_PUBLIC(iter_op_table);
    247 
    248 static VECTOR_PUBLIC(iter_op_table) VECTOR_PUBLIC(iter_ops) =
    249 {
    250     VECTOR_PUBLIC(iter_init),
    251     VECTOR_PUBLIC(iter_target),
    252     VECTOR_PUBLIC(iter_incr),
    253     VECTOR_PUBLIC(iter_lt),
    254     VECTOR_PUBLIC(iter_eq)
    255 };
    256 
    257 /* We need to undefine anything we have defined (and for convenience we also
    258  * undefine our "parameter" macros) as this header may be included multiple
    259  * times in one source file with different parameters. */
    260 #undef VECTOR_CONCAT
    261 #undef VECTOR_XCONCAT
    262 #undef VECTOR_PUBLIC
    263 #undef VECTOR_INTERN
    264 #undef VECTOR_ELEMENT_SIZE
    265 #undef VECTOR_ALLOC_UNIT
    266 #undef VECTOR_TYPE
    267 #undef VECTOR_TYPENAME
    268 #undef VECTOR_ALLOCATOR
    269 #undef VECTOR_DESTRUCTOR
     119#define VEC_EXPAND(pvec) vecExpand(&(pvec)->mcCapacity, &(pvec)->mpvaElements, \
     120                                   (pvec)->mcbElement)
     121
     122/** Reset a vector, cleaning up all its elements. */
     123DECLINLINE(void) vecClearObj(VECTOR_OBJ *pvec)
     124{
     125    unsigned i;
     126
     127    for (i = 0; i < pvec->mcElements; ++i)
     128        pvec->mpfnCleanup(VEC_GET_ELEMENT_OBJ(pvec->mpvaElements,
     129                                              pvec->mcbElement, i));
     130    pvec->mcElements = 0;
     131}
     132
     133/** Reset a pointer vector, cleaning up all its elements. */
     134DECLINLINE(void) vecClearPtr(VECTOR_PTR *pvec)
     135{
     136    unsigned i;
     137
     138    for (i = 0; i < pvec->mcElements; ++i)
     139        pvec->mpfnCleanup(VEC_GET_ELEMENT_PTR(pvec->mpvaElements, i));
     140    pvec->mcElements = 0;
     141}
     142
     143/** Clean up a vector */
     144DECLINLINE(void) vecCleanupObj(VECTOR_OBJ *pvec)
     145{
     146    vecClearObj(pvec);
     147    RTMemFree(pvec->mpvaElements);
     148    pvec->mpvaElements = NULL;
     149}
     150
     151/** Clean up a pointer vector */
     152DECLINLINE(void) vecCleanupPtr(VECTOR_PTR *pvec)
     153{
     154    vecClearPtr(pvec);
     155    RTMemFree(pvec->mpvaElements);
     156    pvec->mpvaElements = NULL;
     157}
     158
     159/** Initialise a vector structure, implementation */
     160#define VEC_INIT(pvec, cbElement, uTypeHash, pfnCleanup) \
     161    pvec->mcElements = pvec->mcCapacity = 0; \
     162    pvec->mcbElement = cbElement; \
     163    pvec->muTypeHash = uTypeHash; \
     164    pvec->mpfnCleanup = pfnCleanup ? pfnCleanup : vecNoCleanup; \
     165    pvec->mpvaElements = NULL; \
     166    return VEC_EXPAND(pvec);
     167
     168/** Initialise a vector. */
     169DECLINLINE(int) vecInitObj(VECTOR_OBJ *pvec, size_t cbElement,
     170                             unsigned uTypeHash, void (*pfnCleanup)(void *))
     171{
     172    VEC_INIT(pvec, cbElement, uTypeHash, pfnCleanup)
     173}
     174
     175/** Initialise a pointer vector. */
     176DECLINLINE(int) vecInitPtr(VECTOR_PTR *pvec, size_t cbElement,
     177                             unsigned uTypeHash, void (*pfnCleanup)(void *))
     178{
     179    VEC_INIT(pvec, cbElement, uTypeHash, pfnCleanup)
     180}
     181
     182/** Add an element onto the end of a vector */
     183DECLINLINE(int) vecPushBackObj(VECTOR_OBJ *pvec, unsigned uTypeHash,
     184                                 void *pvElement)
     185{
     186    int rc2;
     187    AssertReturn(pvec->muTypeHash == uTypeHash, VERR_INVALID_PARAMETER);
     188    if (   pvec->mcElements == pvec->mcCapacity
     189        && RT_FAILURE((rc2 = VEC_EXPAND(pvec))))
     190        return rc2;
     191    memcpy(VEC_GET_ELEMENT_OBJ(pvec->mpvaElements, pvec->mcbElement,
     192                               pvec->mcElements), pvElement, pvec->mcbElement);
     193    ++pvec->mcElements;
     194    return VINF_SUCCESS;
     195}
     196
     197/** Add a pointer onto the end of a pointer vector */
     198DECLINLINE(int) vecPushBackPtr(VECTOR_PTR *pvec, unsigned uTypeHash,
     199                                 void *pv)
     200{
     201    int rc2;
     202    AssertReturn(pvec->muTypeHash == uTypeHash, VERR_INVALID_PARAMETER);
     203    if (   pvec->mcElements == pvec->mcCapacity
     204        && RT_FAILURE((rc2 = VEC_EXPAND(pvec))))
     205        return rc2;
     206    VEC_GET_ELEMENT_PTR(pvec->mpvaElements, pvec->mcElements) = pv;
     207    ++pvec->mcElements;
     208    return VINF_SUCCESS;
     209}
     210
     211/*** Public interface macros ***/
     212
     213/**
     214 * Initialise a vector structure.
     215 * @returns iprt status code (VINF_SUCCESS or VERR_NO_MEMORY)
     216 * @param   pvec        pointer to an uninitialised vector structure
     217 * @param   type        the type of the objects in the vector.  As this is
     218 *                      hashed by the preprocessor use of space etc is
     219 *                      important.
     220 * @param   pfnCleanup  cleanup function (void (*pfn)(void *)) that is called
     221 *                      on a pointer to a vector element when that element is
     222 *                      dropped
     223 */
     224#define VEC_INIT_OBJ(pvec, type, pfnCleanup) \
     225    vecInitObj(pvec, sizeof(type), VECTOR_TOKEN_HASH(type), \
     226               (void (*)(void*)) pfnCleanup)
     227
     228/**
     229 * Initialise a vector-of-pointers structure.
     230 * @returns iprt status code (VINF_SUCCESS or VERR_NO_MEMORY)
     231 * @param   pvec        pointer to an uninitialised vector structure
     232 * @param   type        the type of the pointers in the vector, including the
     233 *                      final "*".  As this is hashed by the preprocessor use
     234 *                      of space etc is important.
     235 * @param   pfnCleanup  cleanup function (void (*pfn)(void *)) that is called
     236 *                      directly on a vector element when that element is
     237 *                      dropped
     238 */
     239#define VEC_INIT_PTR(pvec, type, pfnCleanup) \
     240    vecInitPtr(pvec, sizeof(type), VECTOR_TOKEN_HASH(type), \
     241               (void (*)(void*)) pfnCleanup)
     242
     243/**
     244 * Clean up a vector.
     245 * @param pvec  pointer to the vector to clean up.  The clean up function
     246 *              specified at initialisation (if any) is called for each element
     247 *              in the vector.  After clean up, the vector structure is invalid
     248 *              until it is re-initialised
     249 */
     250#define VEC_CLEANUP_OBJ vecCleanupObj
     251
     252/**
     253 * Clean up a vector-of-pointers.
     254 * @param pvec  pointer to the vector to clean up.  The clean up function
     255 *              specified at initialisation (if any) is called for each element
     256 *              in the vector.  After clean up, the vector structure is invalid
     257 *              until it is re-initialised
     258 */
     259#define VEC_CLEANUP_PTR vecCleanupPtr
     260
     261/**
     262 * Reinitialises a vector structure to empty.
     263 * @param  pvec  pointer to the vector to re-initialise.  The clean up function
     264 *               specified at initialisation (if any) is called for each element
     265 *               in the vector.
     266 */
     267#define VEC_CLEAR_OBJ vecClearObj
     268
     269/**
     270 * Reinitialises a vector-of-pointers structure to empty.
     271 * @param  pvec  pointer to the vector to re-initialise.  The clean up function
     272 *               specified at initialisation (if any) is called for each element
     273 *               in the vector.
     274 */
     275#define VEC_CLEAR_PTR vecClearPtr
     276
     277/**
     278 * Adds an element to the back of a vector.  The element will be byte-copied
     279 * and become owned by the vector, to be cleaned up by the vector's clean-up
     280 * routine when the element is dropped.
     281 * @returns iprt status code (VINF_SUCCESS or VERR_NO_MEMORY)
     282 * @returns VERR_INVALID_PARAMETER if the type does not match the type given
     283 *          when the vector was initialised (asserted)
     284 * @param pvec       pointer to the vector on to which the element should be
     285 *                   added
     286 * @param type       the type of the vector as specified at initialisation.
     287 *                   Spacing etc is important.
     288 * @param pvElement  void pointer to the element to be added
     289 */
     290#define VEC_PUSH_BACK_OBJ(pvec, type, pvElement) \
     291    vecPushBackObj(pvec, VECTOR_TOKEN_HASH(type), \
     292                   (pvElement) + ((pvElement) - (type *)(pvElement)))
     293
     294/**
     295 * Adds a pointer to the back of a vector-of-pointers.  The pointer will become
     296 * owned by the vector, to be cleaned up by the vector's clean-up routine when
     297 * it is dropped.
     298 * @returns iprt status code (VINF_SUCCESS or VERR_NO_MEMORY)
     299 * @returns VERR_INVALID_PARAMETER if the type does not match the type given
     300 *          when the vector was initialised (asserted)
     301 * @param pvec       pointer to the vector on to which the element should be
     302 *                   added
     303 * @param type       the type of the vector as specified at initialisation.
     304 *                   Spacing etc is important.
     305 * @param pvElement  the pointer to be added, typecast to pointer-to-void
     306 */
     307#define VEC_PUSH_BACK_PTR(pvec, type, pvElement) \
     308    vecPushBackPtr(pvec, VECTOR_TOKEN_HASH(type), \
     309                   (pvElement) + ((pvElement) - (type)(pvElement)))
     310
     311/**
     312 * Returns the count of elements in a vector.
     313 * @param  pvec  pointer to the vector.
     314 */
     315#define VEC_SIZE_OBJ(pvec) (pvec)->mcElements
     316
     317/**
     318 * Returns the count of elements in a vector-of-pointers.
     319 * @param  pvec  pointer to the vector.
     320 */
     321#define VEC_SIZE_PTR VEC_SIZE_OBJ
     322
     323/**
     324 * Iterates over the vector elements from first to last and execute the
     325 * following instruction or block on each iteration with @a pIterator set to
     326 * point to the current element (that is, a pointer to the pointer element for
     327 * a vector-of-pointers).  Use in the same way as a "for" statement.
     328 * @param pvec       pointer to the vector to be iterated over
     329 * @param type       the type of the vector, must match the type specified at
     330 *                   vector initialisation (including whitespace etc)
     331 * @todo  can we assert the correctness of the type in some way?
     332 * @param pIterator  a pointer to @a type which will be set to point to the
     333 *                   current vector element on each iteration
     334 */
     335#define VEC_FOR_EACH(pvec, type, pIterator) \
     336    for (pIterator = (type *) (pvec)->mpvaElements; \
     337            (pvec)->muTypeHash == VECTOR_TOKEN_HASH(type) \
     338         && pIterator < (type *) (pvec)->mpvaElements + (pvec)->mcElements; \
     339         ++pIterator)
     340
     341#endif /* MAIN_VECTOR_H */
  • trunk/src/VBox/Main/linux/HostHardwareLinux.cpp

    r32143 r32258  
    2525
    2626#include <HostHardwareLinux.h>
     27#include <vector.h>
    2728
    2829#include <VBox/err.h>
     
    9293#ifdef VBOX_USB_WITH_SYSFS
    9394# ifdef VBOX_USB_WITH_INOTIFY
    94 static int getUSBDeviceInfoFromSysfs(USBDeviceInfoList *pList, bool *pfSuccess);
     95static int getUSBDeviceInfoFromSysfs(VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo,
     96                                     bool *pfSuccess);
    9597
    9698/** Function object to be invoked on filenames from a directory. */
     
    110112    return pHandler->handle(pHandler, pcszNode);
    111113}
    112 
    113 /** Vector of char *-s for holding directory entries */
    114 #define VECTOR_TYPE       char *
    115 #define VECTOR_TYPENAME   filePaths
    116 static inline void filePathsCleanup(char **ppsz)
    117 {
    118     free(*ppsz);
    119 }
    120 #define VECTOR_DESTRUCTOR filePathsCleanup
    121 #include "vector.h"
    122114
    123115static int walkDirectory(const char *pcszPath, pathHandler *pHandler,
     
    10081000}
    10091001
    1010 /** Vector type for the list of interfaces. */
    1011 #define VECTOR_TYPE       char *
    1012 #define VECTOR_TYPENAME   usbInterfaceList
    1013 static void usbInterfaceListCleanup(char **ppsz)
    1014 {
    1015     RTStrFree(*ppsz);
    1016 }
    1017 #define VECTOR_DESTRUCTOR usbInterfaceListCleanup
    1018 #include "vector.h"
    1019 
    1020 struct USBInterfaceList
    1021 {
    1022     /** The vector of devices */
    1023     usbInterfaceList mList;
    1024     /** The single traversal iterator */
    1025     usbInterfaceList_iterator mIt;
    1026 };
    1027 
    10281002void USBDevInfoCleanup(USBDeviceInfo *pSelf)
    10291003{
     
    10311005    RTStrFree(pSelf->mSysfsPath);
    10321006    pSelf->mDevice = pSelf->mSysfsPath = NULL;
    1033     if (pSelf->mInterfaces)
    1034     {
    1035         usbInterfaceList_cleanup(&pSelf->mInterfaces->mList);
    1036         RTMemFree(pSelf->mInterfaces);
    1037     }
     1007    VEC_CLEANUP_PTR(&pSelf->mvecpszInterfaces);
    10381008}
    10391009
     
    10411011                   const char *aSystemID)
    10421012{
    1043     const usbInterfaceList_iterator *pItBegin;
    1044 
    10451013    pSelf->mDevice = aDevice ? RTStrDup(aDevice) : NULL;
    10461014    pSelf->mSysfsPath = aSystemID ? RTStrDup(aSystemID) : NULL;
    1047     pSelf->mInterfaces = (struct USBInterfaceList *) RTMemAllocZ(sizeof(struct USBInterfaceList));
    1048     if (   !pSelf->mInterfaces
    1049         || !usbInterfaceList_init(&pSelf->mInterfaces->mList)
     1015    if (   RT_FAILURE(VEC_INIT_PTR(&pSelf->mvecpszInterfaces, char *, RTStrFree))
    10501016        || (aDevice && !pSelf->mDevice) || (aSystemID && ! pSelf->mSysfsPath))
    10511017    {
     
    10531019        return 0;
    10541020    }
    1055     pItBegin = usbInterfaceList_begin(&pSelf->mInterfaces->mList);
    1056     usbInterfaceList_iter_init(&pSelf->mInterfaces->mIt, pItBegin);
    10571021    return 1;
    10581022}
     
    10631027    int rc = VINF_SUCCESS;
    10641028    bool success = false;  /* Have we succeeded in finding anything yet? */
    1065     USBDeviceInfoList_clear(&pSelf->mDeviceList);
     1029    VEC_CLEAR_OBJ(&pSelf->mvecDevInfo);
    10661030#ifdef VBOX_USB_WITH_SYSFS
    10671031# ifdef VBOX_USB_WITH_INOTIFY
    10681032    if (   RT_SUCCESS(rc)
    10691033        && (!success || testing()))
    1070         rc = getUSBDeviceInfoFromSysfs(&pSelf->mDeviceList, &success);
     1034        rc = getUSBDeviceInfoFromSysfs(&pSelf->mvecDevInfo, &success);
    10711035# endif
    10721036#else /* !VBOX_USB_WITH_SYSFS */
     
    10751039    LogFlowFunc(("rc=%Rrc\n", rc));
    10761040    return rc;
    1077 }
    1078 
    1079 char *USBDevInfoFirstInterface(struct USBInterfaceList *pInterfaces)
    1080 {
    1081     const usbInterfaceList_iterator *pItBegin, *pItEnd;
    1082     pItBegin = usbInterfaceList_begin(&pInterfaces->mList);
    1083     pItEnd = usbInterfaceList_end(&pInterfaces->mList);
    1084     usbInterfaceList_iter_init(&pInterfaces->mIt, pItBegin);
    1085     if (usbInterfaceList_iter_eq(pItBegin, pItEnd))
    1086         return NULL;
    1087     return *usbInterfaceList_iter_target(&pInterfaces->mIt);
    1088 }
    1089 
    1090 char *USBDevInfoNextInterface(struct USBInterfaceList *pInterfaces)
    1091 {
    1092     const usbInterfaceList_iterator *pItEnd;
    1093     pItEnd = usbInterfaceList_end(&pInterfaces->mList);
    1094     if (usbInterfaceList_iter_eq(&pInterfaces->mIt, pItEnd))
    1095         return NULL;
    1096     usbInterfaceList_iter_incr(&pInterfaces->mIt);
    1097     if (usbInterfaceList_iter_eq(&pInterfaces->mIt, pItEnd))
    1098         return NULL;
    1099     return *usbInterfaceList_iter_target(&pInterfaces->mIt);
    11001041}
    11011042
     
    14561397 * NULL and not a dotfile (".", "..", ".*"). */
    14571398static int maybeAddPathToVector(const char *pcszPath, const char *pcszEntry,
    1458                                 filePaths *pvpchDevs)
    1459 {
    1460     filePaths_op_table *pOps = &filePaths_ops;
     1399                                VECTOR_PTR(char *) *pvpchDevs)
     1400{
    14611401    char *pszPath;
    14621402
     
    14651405    if (pcszEntry[0] == '.')
    14661406        return 0;
    1467     pszPath = strdup(pcszPath);
     1407    pszPath = RTStrDup(pcszPath);
    14681408    if (!pszPath)
    14691409        return ENOMEM;
    1470     if (!pOps->push_back(pvpchDevs, &pszPath))
     1410    if (RT_FAILURE(VEC_PUSH_BACK_PTR(pvpchDevs, char *, pszPath)))
    14711411        return ENOMEM;
    14721412    return 0;
     
    14771417 * realpath() and skipping hidden files and files on which realpath() fails. */
    14781418static int readFilePathsFromDir(const char *pcszPath, DIR *pDir,
    1479                                 filePaths *pvpchDevs, int withRealPath)
     1419                                VECTOR_PTR(char *) *pvpchDevs, int withRealPath)
    14801420{
    14811421    struct dirent entry, *pResult;
     
    15111451 * @param   withRealPath  whether to canonicalise the filename with realpath
    15121452 */
    1513 static int readFilePaths(const char *pcszPath, filePaths *pvpchDevs,
     1453static int readFilePaths(const char *pcszPath, VECTOR_PTR(char *) *pvpchDevs,
    15141454                         int withRealPath)
    15151455{
    1516     filePaths_op_table *pOps = &filePaths_ops;
    15171456    DIR *pDir;
    15181457    int err;
    15191458
    15201459    AssertPtrReturn(pvpchDevs, EINVAL);
    1521     AssertReturn(pOps->size(pvpchDevs) == 0, EINVAL);
     1460    AssertReturn(VEC_SIZE_PTR(pvpchDevs) == 0, EINVAL);
    15221461    AssertPtrReturn(pcszPath, EINVAL);
    15231462
     
    15421481 * @param   pHandler     Handler object which will be invoked on each file
    15431482 */
    1544 static int walkFiles(filePaths *pvpchDevs, pathHandler *pHandler)
    1545 {
    1546     filePaths_op_table *pOps = &filePaths_ops;
    1547     filePaths_iter_op_table *pItOps = &filePaths_iter_ops;
    1548     filePaths_iterator it;
     1483static int walkFiles(VECTOR_PTR(char *) *pvpchDevs, pathHandler *pHandler)
     1484{
     1485    char **ppszEntry;
    15491486
    15501487    AssertPtrReturn(pvpchDevs, EINVAL);
    15511488    AssertPtrReturn(pHandler, EINVAL);
    15521489
    1553     pItOps->init(&it, pOps->begin(pvpchDevs));
    1554     for (; !pItOps->eq(&it, pOps->end(pvpchDevs)); pItOps->incr(&it))
    1555     {
    1556         const char *pszEntry;
    1557 
    1558         pszEntry = *pItOps->target(&it);
    1559         if (!pszEntry)
    1560             return ENOMEM;
    1561         if (!phDoHandle(pHandler, pszEntry))
     1490    VEC_FOR_EACH(pvpchDevs, char *, ppszEntry)
     1491        if (!phDoHandle(pHandler, *ppszEntry))
    15621492            break;
    1563     }
    15641493    return 0;
    15651494}
     
    15791508int walkDirectory(const char *pcszPath, pathHandler *pHandler, int withRealPath)
    15801509{
    1581     filePaths vpchDevs;
    1582     filePaths_init(&vpchDevs);
     1510    VECTOR_PTR(char *) vpchDevs;
    15831511    int rc;
    15841512
     
    15861514    AssertReturn(pcszPath[strlen(pcszPath)] != '/', VERR_INVALID_PARAMETER);
    15871515
     1516    if (RT_FAILURE((rc = VEC_INIT_PTR(&vpchDevs, char *, RTStrFree))))
     1517        return rc;
    15881518    rc = readFilePaths(pcszPath, &vpchDevs, withRealPath);
    15891519    if (!rc)
    15901520        rc = walkFiles(&vpchDevs, pHandler);
    1591     filePaths_cleanup(&vpchDevs);
     1521    VEC_CLEANUP_PTR(&vpchDevs);
    15921522    return RTErrConvertFromErrno(rc);
    15931523}
     
    16241554    /** The pathHandler object we inherit from - must come first */
    16251555    pathHandler mParent;
    1626     USBDeviceInfoList *mList;
     1556    VECTOR_OBJ(USBDeviceInfo) *mpvecDevInfo;
    16271557} matchUSBDevice;
    16281558
     
    16531583    USBDeviceInfo info;
    16541584    if (USBDevInfoInit(&info, szDevPath, pcszNode))
    1655         if (USBDeviceInfoList_push_back(pSelf->mList, &info))
     1585        if (RT_SUCCESS(VEC_PUSH_BACK_OBJ(pSelf->mpvecDevInfo, USBDeviceInfo,
     1586                                         &info)))
    16561587            return true;
    16571588    USBDevInfoCleanup(&info);
     
    16591590}
    16601591
    1661 static void mudInit(matchUSBDevice *pSelf, USBDeviceInfoList *pList)
     1592static void mudInit(matchUSBDevice *pSelf,
     1593                    VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo)
    16621594{
    16631595    AssertPtrReturnVoid(pSelf);
    16641596    pSelf->mParent.handle = mudHandle;
    1665     pSelf->mList = pList;
     1597    pSelf->mpvecDevInfo = pvecDevInfo;
    16661598}
    16671599
     
    17141646    if (!muiIsAnInterfaceOf(pcszNode, pSelf->mInfo->mSysfsPath))
    17151647        return true;
    1716     char *pcszDup = RTStrDup(pcszNode);
    1717     if (pcszDup)
    1718         if (usbInterfaceList_push_back(&pSelf->mInfo->mInterfaces->mList,
    1719                                        &pcszDup))
     1648    char *pszDup = (char *)RTStrDup(pcszNode);
     1649    if (pszDup)
     1650        if (RT_SUCCESS(VEC_PUSH_BACK_PTR(&pSelf->mInfo->mvecpszInterfaces,
     1651                                         char *, pszDup)))
    17201652            return true;
    1721     RTStrFree(pcszDup);
     1653    RTStrFree(pszDup);
    17221654    return false;
    17231655}
     
    17481680 * @returns IPRT status code
    17491681 */
    1750 static int getUSBDeviceInfoFromSysfs(USBDeviceInfoList *pList,
    1751                                      bool *pfSuccess)
    1752 {
    1753     AssertPtrReturn(pList, VERR_INVALID_POINTER);
     1682/* static */
     1683int getUSBDeviceInfoFromSysfs(VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo,
     1684                              bool *pfSuccess)
     1685{
     1686    AssertPtrReturn(pvecDevInfo, VERR_INVALID_POINTER);
    17541687    AssertPtrNullReturn(pfSuccess, VERR_INVALID_POINTER); /* Valid or Null */
    1755     LogFlowFunc (("pList=%p, pfSuccess=%p\n",
    1756                   pList, pfSuccess));
     1688    LogFlowFunc (("pvecDevInfo=%p, pfSuccess=%p\n",
     1689                  pvecDevInfo, pfSuccess));
    17571690    matchUSBDevice devHandler;
    1758     mudInit(&devHandler, pList);
     1691    mudInit(&devHandler, pvecDevInfo);
    17591692    int rc = walkDirectory("/sys/bus/usb/devices", &devHandler.mParent, true);
    17601693    do {
    17611694        if (RT_FAILURE(rc))
    17621695            break;
    1763         USBDeviceInfoList_iterator info;
    1764         USBDeviceInfoList_iter_init(&info,
    1765                                     USBDeviceInfoList_begin(pList));
    1766         while (!USBDeviceInfoList_iter_eq(&info,
    1767                                           USBDeviceInfoList_end(pList)))
     1696        USBDeviceInfo *pInfo;
     1697        VEC_FOR_EACH(pvecDevInfo, USBDeviceInfo, pInfo)
    17681698        {
    17691699            matchUSBInterface ifaceHandler;
    1770             muiInit(&ifaceHandler, USBDeviceInfoList_iter_target(&info));
     1700            muiInit(&ifaceHandler, pInfo);
    17711701            rc = walkDirectory("/sys/bus/usb/devices", &ifaceHandler.mParent,
    17721702                               true);
    17731703            if (RT_FAILURE(rc))
    17741704                break;
    1775             USBDeviceInfoList_iter_incr(&info);
    17761705        }
    17771706    } while(0);
  • trunk/src/VBox/Main/linux/USBProxyServiceLinux.cpp

    r32142 r32258  
    263263
    264264#ifdef VBOX_USB_WITH_SYSFS
    265     if (!VBoxMainUSBDevInfoInit(&mDeviceList))
    266         return VERR_NO_MEMORY;
     265    int rc2;
     266    if (RT_FAILURE((rc2 = VBoxMainUSBDevInfoInit(&mDeviceList))))
     267        return rc2;
    267268    int rc = mWaiter.getStatus();
    268269    if (RT_SUCCESS(rc) || rc == VERR_TIMEOUT || rc == VERR_TRY_AGAIN)
     
    13441345    PUSBDEVICE pLast  = NULL;
    13451346    int        rc     = USBDevInfoUpdateDevices(&mDeviceList);
    1346     USBDeviceInfoList_iterator it;
    1347     USBDeviceInfoList_iter_init(&it, USBDevInfoBegin(&mDeviceList));
    1348     for (;    RT_SUCCESS(rc)
    1349            && !USBDeviceInfoList_iter_eq(&it, USBDevInfoEnd(&mDeviceList));
    1350            USBDeviceInfoList_iter_incr(&it))
     1347    USBDeviceInfo *pInfo;
     1348    VEC_FOR_EACH(&mDeviceList.mvecDevInfo, USBDeviceInfo, pInfo)
    13511349    {
    13521350        USBDEVICE *Dev = (USBDEVICE *)RTMemAllocZ(sizeof(USBDEVICE));
     
    13551353        if (RT_SUCCESS(rc))
    13561354        {
    1357             const char *pszSysfsPath = USBDeviceInfoList_iter_target(&it)->mSysfsPath;
     1355            const char *pszSysfsPath = pInfo->mSysfsPath;
    13581356
    13591357            /* Fill in the simple fields */
     
    14411439
    14421440            /* Check the interfaces to see if we can support the device. */
    1443             char *pszIf;
    1444             USBDeviceInfo *udi = USBDeviceInfoList_iter_target(&it);
    1445             for (pszIf = USBDevInfoFirstInterface(udi->mInterfaces); pszIf;
    1446                  pszIf = USBDevInfoNextInterface(udi->mInterfaces))
     1441            char **ppszIf;
     1442            VEC_FOR_EACH(&pInfo->mvecpszInterfaces, char *, ppszIf)
    14471443            {
    14481444                ssize_t cb = RTLinuxSysFsGetLinkDest(szBuf, sizeof(szBuf), "%s/driver",
    1449                                                      pszIf);
     1445                                                     *ppszIf);
    14501446                if (cb > 0 && Dev->enmState != USBDEVICESTATE_UNSUPPORTED)
    14511447                    Dev->enmState = (strcmp(szBuf, "hub") == 0)
     
    14531449                                  : USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
    14541450                if (RTLinuxSysFsReadIntFile(16, "%s/bInterfaceClass",
    1455                                             pszIf) == 9 /* hub */)
     1451                                            *ppszIf) == 9 /* hub */)
    14561452                    Dev->enmState = USBDEVICESTATE_UNSUPPORTED;
    14571453            }
     
    14631459            char szSysfsClean[RTPATH_MAX];
    14641460            char *pszAddress = NULL;
    1465             if (   RT_SUCCESS(RTPathReal(USBDeviceInfoList_iter_target(&it)->mDevice, szDeviceClean,
     1461            if (   RT_SUCCESS(RTPathReal(pInfo->mDevice, szDeviceClean,
    14661462                                         sizeof(szDeviceClean)))
    14671463                && RT_SUCCESS(RTPathReal(pszSysfsPath, szSysfsClean,
     
    14911487        else
    14921488            freeDevice(Dev);
     1489        if (RT_FAILURE(rc))
     1490            break;
    14931491    }
    14941492    if (RT_FAILURE(rc))
  • trunk/src/VBox/Main/testcase/tstHostHardwareLinux.cpp

    r32142 r32258  
    9292#ifdef VBOX_USB_WITH_SYSFS
    9393    VBoxMainUSBDeviceInfo deviceInfo;
    94     AssertReturn(VBoxMainUSBDevInfoInit(&deviceInfo), 1);
     94    AssertRCReturn(VBoxMainUSBDevInfoInit(&deviceInfo), 1);
    9595    rc = USBDevInfoUpdateDevices(&deviceInfo);
    9696    if (RT_FAILURE(rc))
     
    101101    }
    102102    RTPrintf ("Listing USB devices detected:\n");
    103     USBDeviceInfoList_iterator it;
    104     USBDeviceInfoList_iter_init(&it, USBDevInfoBegin(&deviceInfo));
    105     for (; !USBDeviceInfoList_iter_eq(&it, USBDevInfoEnd(&deviceInfo));
    106            USBDeviceInfoList_iter_incr(&it))
     103    USBDeviceInfo *pInfo;
     104    VEC_FOR_EACH(&deviceInfo.mvecDevInfo, USBDeviceInfo, pInfo)
    107105    {
    108106        char szProduct[1024];
    109         USBDeviceInfo *pInfo = USBDeviceInfoList_iter_target(&it);
    110107        if (RTLinuxSysFsReadStrFile(szProduct, sizeof(szProduct),
    111108                                    "%s/product", pInfo->mSysfsPath) == -1)
     
    123120                  pInfo->mSysfsPath);
    124121        RTPrintf ("    interfaces:\n");
    125         char *pszIf;
    126         for (pszIf = USBDevInfoFirstInterface(pInfo->mInterfaces); pszIf;
    127              pszIf = USBDevInfoNextInterface(pInfo->mInterfaces))
     122        char **ppszIf;
     123        VEC_FOR_EACH(&pInfo->mvecpszInterfaces, char *, ppszIf)
    128124        {
    129125            char szDriver[RTPATH_MAX];
    130126            strcpy(szDriver, "none");
    131127            ssize_t size = RTLinuxSysFsGetLinkDest(szDriver, sizeof(szDriver),
    132                                                    "%s/driver", pszIf);
     128                                                   "%s/driver", *ppszIf);
    133129            if (size == -1 && errno != ENOENT)
    134130            {
    135131                RTPrintf ("Failed to get the driver for interface %s of device %s: error %s\n",
    136                           pszIf, pInfo->mDevice, strerror(errno));
     132                          *ppszIf, pInfo->mDevice, strerror(errno));
    137133                return 1;
    138134            }
    139             if (RTLinuxSysFsExists("%s/driver", pszIf) != (size != -1))
     135            if (RTLinuxSysFsExists("%s/driver", *ppszIf) != (size != -1))
    140136            {
    141137                RTPrintf ("RTLinuxSysFsExists did not return the expected value for the driver link of interface %s of device %s.\n",
    142                           pszIf, pInfo->mDevice);
     138                          *ppszIf, pInfo->mDevice);
    143139                return 1;
    144140            }
    145141            uint64_t u64InterfaceClass;
    146142            u64InterfaceClass = RTLinuxSysFsReadIntFile(16, "%s/bInterfaceClass",
    147                                                         pszIf);
     143                                                        *ppszIf);
    148144            RTPrintf ("      sysfs path: %s, driver: %s, interface class: 0x%x\n",
    149                       pszIf, szDriver, u64InterfaceClass);
     145                      *ppszIf, szDriver, u64InterfaceClass);
    150146        }
    151147    }
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