- Timestamp:
- Sep 6, 2010 8:33:08 PM (14 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/HostHardwareLinux.h
r32142 r32258 25 25 #include <iprt/cpp/ministring.h> 26 26 #include <vector> 27 #include <vector.h> 27 28 28 29 /** … … 118 119 * method. */ 119 120 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; 122 123 } USBDeviceInfo; 123 124 … … 130 131 131 132 /** 132 * Return the first in a list of USB device interfaces (that is, its sysfs133 * 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 sysfs139 * 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 USBDeviceInfo146 #define VECTOR_TYPENAME USBDeviceInfoList147 #define VECTOR_DESTRUCTOR USBDevInfoCleanup148 #include "vector.h"149 150 151 /**152 133 * Class for probing and returning information about host USB devices. 153 134 * To use this class, create an instance, call the update methods to do the … … 157 138 { 158 139 /** The list of currently available USB devices */ 159 USBDeviceInfoList mDeviceList;140 VECTOR_OBJ(USBDeviceInfo) mvecDevInfo; 160 141 } VBoxMainUSBDeviceInfo; 161 142 … … 163 144 static inline int VBoxMainUSBDevInfoInit(VBoxMainUSBDeviceInfo *pSelf) 164 145 { 165 return USBDeviceInfoList_init(&pSelf->mDeviceList);146 return VEC_INIT_OBJ(&pSelf->mvecDevInfo, USBDeviceInfo, USBDevInfoCleanup); 166 147 } 167 148 … … 169 150 static inline void VBoxMainUSBDevInfoCleanup(VBoxMainUSBDeviceInfo *pSelf) 170 151 { 171 USBDeviceInfoList_cleanup(&pSelf->mDeviceList);152 VEC_CLEANUP_OBJ(&pSelf->mvecDevInfo); 172 153 } 173 154 … … 178 159 */ 179 160 int USBDevInfoUpdateDevices(VBoxMainUSBDeviceInfo *pSelf); 180 181 /** Get the first element in the list of USB devices. */182 static inline const USBDeviceInfoList_iterator *USBDevInfoBegin183 (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 *USBDevInfoEnd191 (VBoxMainUSBDeviceInfo *pSelf)192 {193 return USBDeviceInfoList_end(&pSelf->mDeviceList);194 }195 161 196 162 -
trunk/src/VBox/Main/include/vector.h
r32114 r32258 1 1 /** @file 2 * STL- likevector implementation in C2 * STL-inspired vector implementation in C 3 3 * @note functions in this file are inline to prevent warnings about 4 4 * unused static functions. I assume that in this day and age a 5 5 * compiler makes its own decisions about whether to actually 6 6 * 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? 7 12 */ 8 13 … … 19 24 */ 20 25 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 29 31 /** The unit by which the vector capacity is increased */ 30 32 #define VECTOR_ALLOC_UNIT 16 31 33 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 */ 73 typedef struct VECTOR_OBJ VECTOR_STRUCT VECTOR_OBJ; 74 75 /** A vector of pointer values. (A handy special case.) */ 76 typedef 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. */ 96 DECLINLINE(void) vecNoCleanup(void *pvElement) 97 { 98 (void) pvElement; 99 } 100 101 /** Expand an existing vector, implementation */ 102 DECLINLINE(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; 76 116 } 77 117 78 118 /** 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. */ 123 DECLINLINE(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. */ 134 DECLINLINE(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 */ 144 DECLINLINE(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 */ 152 DECLINLINE(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. */ 169 DECLINLINE(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. */ 176 DECLINLINE(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 */ 183 DECLINLINE(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 */ 198 DECLINLINE(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 25 25 26 26 #include <HostHardwareLinux.h> 27 #include <vector.h> 27 28 28 29 #include <VBox/err.h> … … 92 93 #ifdef VBOX_USB_WITH_SYSFS 93 94 # ifdef VBOX_USB_WITH_INOTIFY 94 static int getUSBDeviceInfoFromSysfs(USBDeviceInfoList *pList, bool *pfSuccess); 95 static int getUSBDeviceInfoFromSysfs(VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo, 96 bool *pfSuccess); 95 97 96 98 /** Function object to be invoked on filenames from a directory. */ … … 110 112 return pHandler->handle(pHandler, pcszNode); 111 113 } 112 113 /** Vector of char *-s for holding directory entries */114 #define VECTOR_TYPE char *115 #define VECTOR_TYPENAME filePaths116 static inline void filePathsCleanup(char **ppsz)117 {118 free(*ppsz);119 }120 #define VECTOR_DESTRUCTOR filePathsCleanup121 #include "vector.h"122 114 123 115 static int walkDirectory(const char *pcszPath, pathHandler *pHandler, … … 1008 1000 } 1009 1001 1010 /** Vector type for the list of interfaces. */1011 #define VECTOR_TYPE char *1012 #define VECTOR_TYPENAME usbInterfaceList1013 static void usbInterfaceListCleanup(char **ppsz)1014 {1015 RTStrFree(*ppsz);1016 }1017 #define VECTOR_DESTRUCTOR usbInterfaceListCleanup1018 #include "vector.h"1019 1020 struct USBInterfaceList1021 {1022 /** The vector of devices */1023 usbInterfaceList mList;1024 /** The single traversal iterator */1025 usbInterfaceList_iterator mIt;1026 };1027 1028 1002 void USBDevInfoCleanup(USBDeviceInfo *pSelf) 1029 1003 { … … 1031 1005 RTStrFree(pSelf->mSysfsPath); 1032 1006 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); 1038 1008 } 1039 1009 … … 1041 1011 const char *aSystemID) 1042 1012 { 1043 const usbInterfaceList_iterator *pItBegin;1044 1045 1013 pSelf->mDevice = aDevice ? RTStrDup(aDevice) : NULL; 1046 1014 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)) 1050 1016 || (aDevice && !pSelf->mDevice) || (aSystemID && ! pSelf->mSysfsPath)) 1051 1017 { … … 1053 1019 return 0; 1054 1020 } 1055 pItBegin = usbInterfaceList_begin(&pSelf->mInterfaces->mList);1056 usbInterfaceList_iter_init(&pSelf->mInterfaces->mIt, pItBegin);1057 1021 return 1; 1058 1022 } … … 1063 1027 int rc = VINF_SUCCESS; 1064 1028 bool success = false; /* Have we succeeded in finding anything yet? */ 1065 USBDeviceInfoList_clear(&pSelf->mDeviceList);1029 VEC_CLEAR_OBJ(&pSelf->mvecDevInfo); 1066 1030 #ifdef VBOX_USB_WITH_SYSFS 1067 1031 # ifdef VBOX_USB_WITH_INOTIFY 1068 1032 if ( RT_SUCCESS(rc) 1069 1033 && (!success || testing())) 1070 rc = getUSBDeviceInfoFromSysfs(&pSelf->m DeviceList, &success);1034 rc = getUSBDeviceInfoFromSysfs(&pSelf->mvecDevInfo, &success); 1071 1035 # endif 1072 1036 #else /* !VBOX_USB_WITH_SYSFS */ … … 1075 1039 LogFlowFunc(("rc=%Rrc\n", rc)); 1076 1040 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);1100 1041 } 1101 1042 … … 1456 1397 * NULL and not a dotfile (".", "..", ".*"). */ 1457 1398 static 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 { 1461 1401 char *pszPath; 1462 1402 … … 1465 1405 if (pcszEntry[0] == '.') 1466 1406 return 0; 1467 pszPath = strdup(pcszPath);1407 pszPath = RTStrDup(pcszPath); 1468 1408 if (!pszPath) 1469 1409 return ENOMEM; 1470 if ( !pOps->push_back(pvpchDevs, &pszPath))1410 if (RT_FAILURE(VEC_PUSH_BACK_PTR(pvpchDevs, char *, pszPath))) 1471 1411 return ENOMEM; 1472 1412 return 0; … … 1477 1417 * realpath() and skipping hidden files and files on which realpath() fails. */ 1478 1418 static int readFilePathsFromDir(const char *pcszPath, DIR *pDir, 1479 filePaths*pvpchDevs, int withRealPath)1419 VECTOR_PTR(char *) *pvpchDevs, int withRealPath) 1480 1420 { 1481 1421 struct dirent entry, *pResult; … … 1511 1451 * @param withRealPath whether to canonicalise the filename with realpath 1512 1452 */ 1513 static int readFilePaths(const char *pcszPath, filePaths*pvpchDevs,1453 static int readFilePaths(const char *pcszPath, VECTOR_PTR(char *) *pvpchDevs, 1514 1454 int withRealPath) 1515 1455 { 1516 filePaths_op_table *pOps = &filePaths_ops;1517 1456 DIR *pDir; 1518 1457 int err; 1519 1458 1520 1459 AssertPtrReturn(pvpchDevs, EINVAL); 1521 AssertReturn( pOps->size(pvpchDevs) == 0, EINVAL);1460 AssertReturn(VEC_SIZE_PTR(pvpchDevs) == 0, EINVAL); 1522 1461 AssertPtrReturn(pcszPath, EINVAL); 1523 1462 … … 1542 1481 * @param pHandler Handler object which will be invoked on each file 1543 1482 */ 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; 1483 static int walkFiles(VECTOR_PTR(char *) *pvpchDevs, pathHandler *pHandler) 1484 { 1485 char **ppszEntry; 1549 1486 1550 1487 AssertPtrReturn(pvpchDevs, EINVAL); 1551 1488 AssertPtrReturn(pHandler, EINVAL); 1552 1489 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)) 1562 1492 break; 1563 }1564 1493 return 0; 1565 1494 } … … 1579 1508 int walkDirectory(const char *pcszPath, pathHandler *pHandler, int withRealPath) 1580 1509 { 1581 filePaths vpchDevs; 1582 filePaths_init(&vpchDevs); 1510 VECTOR_PTR(char *) vpchDevs; 1583 1511 int rc; 1584 1512 … … 1586 1514 AssertReturn(pcszPath[strlen(pcszPath)] != '/', VERR_INVALID_PARAMETER); 1587 1515 1516 if (RT_FAILURE((rc = VEC_INIT_PTR(&vpchDevs, char *, RTStrFree)))) 1517 return rc; 1588 1518 rc = readFilePaths(pcszPath, &vpchDevs, withRealPath); 1589 1519 if (!rc) 1590 1520 rc = walkFiles(&vpchDevs, pHandler); 1591 filePaths_cleanup(&vpchDevs);1521 VEC_CLEANUP_PTR(&vpchDevs); 1592 1522 return RTErrConvertFromErrno(rc); 1593 1523 } … … 1624 1554 /** The pathHandler object we inherit from - must come first */ 1625 1555 pathHandler mParent; 1626 USBDeviceInfoList *mList;1556 VECTOR_OBJ(USBDeviceInfo) *mpvecDevInfo; 1627 1557 } matchUSBDevice; 1628 1558 … … 1653 1583 USBDeviceInfo info; 1654 1584 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))) 1656 1587 return true; 1657 1588 USBDevInfoCleanup(&info); … … 1659 1590 } 1660 1591 1661 static void mudInit(matchUSBDevice *pSelf, USBDeviceInfoList *pList) 1592 static void mudInit(matchUSBDevice *pSelf, 1593 VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo) 1662 1594 { 1663 1595 AssertPtrReturnVoid(pSelf); 1664 1596 pSelf->mParent.handle = mudHandle; 1665 pSelf->m List = pList;1597 pSelf->mpvecDevInfo = pvecDevInfo; 1666 1598 } 1667 1599 … … 1714 1646 if (!muiIsAnInterfaceOf(pcszNode, pSelf->mInfo->mSysfsPath)) 1715 1647 return true; 1716 char *p cszDup =RTStrDup(pcszNode);1717 if (p cszDup)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))) 1720 1652 return true; 1721 RTStrFree(p cszDup);1653 RTStrFree(pszDup); 1722 1654 return false; 1723 1655 } … … 1748 1680 * @returns IPRT status code 1749 1681 */ 1750 static int getUSBDeviceInfoFromSysfs(USBDeviceInfoList *pList, 1751 bool *pfSuccess) 1752 { 1753 AssertPtrReturn(pList, VERR_INVALID_POINTER); 1682 /* static */ 1683 int getUSBDeviceInfoFromSysfs(VECTOR_OBJ(USBDeviceInfo) *pvecDevInfo, 1684 bool *pfSuccess) 1685 { 1686 AssertPtrReturn(pvecDevInfo, VERR_INVALID_POINTER); 1754 1687 AssertPtrNullReturn(pfSuccess, VERR_INVALID_POINTER); /* Valid or Null */ 1755 LogFlowFunc (("p List=%p, pfSuccess=%p\n",1756 p List, pfSuccess));1688 LogFlowFunc (("pvecDevInfo=%p, pfSuccess=%p\n", 1689 pvecDevInfo, pfSuccess)); 1757 1690 matchUSBDevice devHandler; 1758 mudInit(&devHandler, p List);1691 mudInit(&devHandler, pvecDevInfo); 1759 1692 int rc = walkDirectory("/sys/bus/usb/devices", &devHandler.mParent, true); 1760 1693 do { 1761 1694 if (RT_FAILURE(rc)) 1762 1695 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) 1768 1698 { 1769 1699 matchUSBInterface ifaceHandler; 1770 muiInit(&ifaceHandler, USBDeviceInfoList_iter_target(&info));1700 muiInit(&ifaceHandler, pInfo); 1771 1701 rc = walkDirectory("/sys/bus/usb/devices", &ifaceHandler.mParent, 1772 1702 true); 1773 1703 if (RT_FAILURE(rc)) 1774 1704 break; 1775 USBDeviceInfoList_iter_incr(&info);1776 1705 } 1777 1706 } while(0); -
trunk/src/VBox/Main/linux/USBProxyServiceLinux.cpp
r32142 r32258 263 263 264 264 #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; 267 268 int rc = mWaiter.getStatus(); 268 269 if (RT_SUCCESS(rc) || rc == VERR_TIMEOUT || rc == VERR_TRY_AGAIN) … … 1344 1345 PUSBDEVICE pLast = NULL; 1345 1346 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) 1351 1349 { 1352 1350 USBDEVICE *Dev = (USBDEVICE *)RTMemAllocZ(sizeof(USBDEVICE)); … … 1355 1353 if (RT_SUCCESS(rc)) 1356 1354 { 1357 const char *pszSysfsPath = USBDeviceInfoList_iter_target(&it)->mSysfsPath;1355 const char *pszSysfsPath = pInfo->mSysfsPath; 1358 1356 1359 1357 /* Fill in the simple fields */ … … 1441 1439 1442 1440 /* 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) 1447 1443 { 1448 1444 ssize_t cb = RTLinuxSysFsGetLinkDest(szBuf, sizeof(szBuf), "%s/driver", 1449 pszIf);1445 *ppszIf); 1450 1446 if (cb > 0 && Dev->enmState != USBDEVICESTATE_UNSUPPORTED) 1451 1447 Dev->enmState = (strcmp(szBuf, "hub") == 0) … … 1453 1449 : USBDEVICESTATE_USED_BY_HOST_CAPTURABLE; 1454 1450 if (RTLinuxSysFsReadIntFile(16, "%s/bInterfaceClass", 1455 pszIf) == 9 /* hub */)1451 *ppszIf) == 9 /* hub */) 1456 1452 Dev->enmState = USBDEVICESTATE_UNSUPPORTED; 1457 1453 } … … 1463 1459 char szSysfsClean[RTPATH_MAX]; 1464 1460 char *pszAddress = NULL; 1465 if ( RT_SUCCESS(RTPathReal( USBDeviceInfoList_iter_target(&it)->mDevice, szDeviceClean,1461 if ( RT_SUCCESS(RTPathReal(pInfo->mDevice, szDeviceClean, 1466 1462 sizeof(szDeviceClean))) 1467 1463 && RT_SUCCESS(RTPathReal(pszSysfsPath, szSysfsClean, … … 1491 1487 else 1492 1488 freeDevice(Dev); 1489 if (RT_FAILURE(rc)) 1490 break; 1493 1491 } 1494 1492 if (RT_FAILURE(rc)) -
trunk/src/VBox/Main/testcase/tstHostHardwareLinux.cpp
r32142 r32258 92 92 #ifdef VBOX_USB_WITH_SYSFS 93 93 VBoxMainUSBDeviceInfo deviceInfo; 94 AssertR eturn(VBoxMainUSBDevInfoInit(&deviceInfo), 1);94 AssertRCReturn(VBoxMainUSBDevInfoInit(&deviceInfo), 1); 95 95 rc = USBDevInfoUpdateDevices(&deviceInfo); 96 96 if (RT_FAILURE(rc)) … … 101 101 } 102 102 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) 107 105 { 108 106 char szProduct[1024]; 109 USBDeviceInfo *pInfo = USBDeviceInfoList_iter_target(&it);110 107 if (RTLinuxSysFsReadStrFile(szProduct, sizeof(szProduct), 111 108 "%s/product", pInfo->mSysfsPath) == -1) … … 123 120 pInfo->mSysfsPath); 124 121 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) 128 124 { 129 125 char szDriver[RTPATH_MAX]; 130 126 strcpy(szDriver, "none"); 131 127 ssize_t size = RTLinuxSysFsGetLinkDest(szDriver, sizeof(szDriver), 132 "%s/driver", pszIf);128 "%s/driver", *ppszIf); 133 129 if (size == -1 && errno != ENOENT) 134 130 { 135 131 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)); 137 133 return 1; 138 134 } 139 if (RTLinuxSysFsExists("%s/driver", pszIf) != (size != -1))135 if (RTLinuxSysFsExists("%s/driver", *ppszIf) != (size != -1)) 140 136 { 141 137 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); 143 139 return 1; 144 140 } 145 141 uint64_t u64InterfaceClass; 146 142 u64InterfaceClass = RTLinuxSysFsReadIntFile(16, "%s/bInterfaceClass", 147 pszIf);143 *ppszIf); 148 144 RTPrintf (" sysfs path: %s, driver: %s, interface class: 0x%x\n", 149 pszIf, szDriver, u64InterfaceClass);145 *ppszIf, szDriver, u64InterfaceClass); 150 146 } 151 147 }
Note:
See TracChangeset
for help on using the changeset viewer.