Changeset 60373 in vbox for trunk/src/VBox/Runtime/r3
- Timestamp:
- Apr 7, 2016 2:21:30 PM (9 years ago)
- Location:
- trunk/src/VBox/Runtime/r3/linux
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/linux/RTSystemQueryDmiString-linux.cpp
r57358 r60373 58 58 } 59 59 60 int rc;61 int fd = RTLinuxSysFsOpen("devices/virtual/dmi/%s", pszSysFsName);62 if ( fd < 0)63 fd = RTLinuxSysFsOpen("class/dmi/%s", pszSysFsName);64 if ( fd >= 0)60 size_t cbRead = 0; 61 int rc = RTLinuxSysFsReadStrFile(pszBuf, cbBuf, &cbRead, "devices/virtual/dmi/%s", pszSysFsName); 62 if (RT_FAILURE(rc) && rc != VERR_BUFFER_OVERFLOW) 63 rc = RTLinuxSysFsReadStrFile(pszBuf, cbBuf, &cbRead, "class/dmi/%s", pszSysFsName); 64 if (RT_FAILURE(rc) && rc != VERR_BUFFER_OVERFLOW) 65 65 { 66 size_t cbRead;67 rc = RTLinuxSysFsReadFile(fd, pszBuf, cbBuf, &cbRead);68 if (RT_SUCCESS(rc) || rc == VERR_BUFFER_OVERFLOW)69 {70 /* The file we're reading may end with a newline, remove it. */71 if (cbRead == cbBuf)72 pszBuf[cbRead - 1] = '\0';73 else74 {75 AssertRC(rc);76 pszBuf[cbRead] = '\0';77 if (cbRead > 0 && pszBuf[cbRead - 1] == '\n')78 pszBuf[cbRead - 1] = '\0';79 }80 }81 RTLinuxSysFsClose(fd);82 }83 else84 {85 rc = RTErrConvertFromErrno(errno);86 66 switch (rc) 87 67 { -
trunk/src/VBox/Runtime/r3/linux/mp-linux.cpp
r57358 r60373 139 139 { 140 140 /** @todo check if there is a simpler interface than this... */ 141 int i = RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/online", (int)idCpu); 142 if ( i == -1 141 int64_t i = 0; 142 int rc = RTLinuxSysFsReadIntFile(0, &i, "devices/system/cpu/cpu%d/online", (int)idCpu); 143 if ( RT_FAILURE(rc) 143 144 && RTLinuxSysFsExists("devices/system/cpu/cpu%d", (int)idCpu)) 144 145 { … … 148 149 * 2.6.18-164). */ 149 150 i = 1; 151 rc = VINF_SUCCESS; 150 152 } 151 153 152 154 AssertMsg(i == 0 || i == -1 || i == 1, ("i=%d\n", i)); 153 return i != 0 && i != -1;155 return RT_SUCCESS(rc) && i != 0; 154 156 } 155 157 … … 191 193 if (RTMpIsCpuPossible(idCpu)) 192 194 { 193 uint32_t idCore = (uint32_t)RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/topology/core_id", (int)idCpu);194 uint32_t idPckg = (uint32_t)RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/topology/physical_package_id", (int)idCpu);195 uint32_t i; 196 for (i = 0; i < cCores; i++)197 if ( paidCores[i] == idCore198 && paidPckgs[i] == idPckg)199 break; 200 if ( i >= cCores)195 int64_t idCore = 0; 196 int64_t idPckg = 0; 197 198 int rc = RTLinuxSysFsReadIntFile(0, &idCore, "devices/system/cpu/cpu%d/topology/core_id", (int)idCpu); 199 if (RT_SUCCESS(rc)) 200 rc = RTLinuxSysFsReadIntFile(0, &idPckg, "devices/system/cpu/cpu%d/topology/physical_package_id", (int)idCpu); 201 202 if (RT_SUCCESS(rc)) 201 203 { 202 paidCores[cCores] = idCore; 203 paidPckgs[cCores] = idPckg; 204 cCores++; 204 uint32_t i; 205 206 for (i = 0; i < cCores; i++) 207 if ( paidCores[i] == (uint32_t)idCore 208 && paidPckgs[i] == (uint32_t)idPckg) 209 break; 210 if (i >= cCores) 211 { 212 paidCores[cCores] = (uint32_t)idCore; 213 paidPckgs[cCores] = (uint32_t)idPckg; 214 cCores++; 215 } 205 216 } 206 217 } … … 240 251 if (RTMpIsCpuOnline(idCpu)) 241 252 { 242 uint32_t idCore = (uint32_t)RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/topology/core_id", (int)idCpu);243 uint32_t idPckg = (uint32_t)RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/topology/physical_package_id", (int)idCpu);244 uint32_t i; 245 for (i = 0; i < cCores; i++)246 if ( paidCores[i] == idCore247 && paidPckgs[i] == idPckg)248 break; 249 if ( i >= cCores)253 int64_t idCore = 0; 254 int64_t idPckg = 0; 255 256 int rc = RTLinuxSysFsReadIntFile(0, &idCore, "devices/system/cpu/cpu%d/topology/core_id", (int)idCpu); 257 if (RT_SUCCESS(rc)) 258 rc = RTLinuxSysFsReadIntFile(0, &idPckg, "devices/system/cpu/cpu%d/topology/physical_package_id", (int)idCpu); 259 260 if (RT_SUCCESS(rc)) 250 261 { 251 paidCores[cCores] = idCore; 252 paidPckgs[cCores] = idPckg; 253 cCores++; 262 uint32_t i; 263 264 for (i = 0; i < cCores; i++) 265 if ( paidCores[i] == idCore 266 && paidPckgs[i] == idPckg) 267 break; 268 if (i >= cCores) 269 { 270 paidCores[cCores] = idCore; 271 paidPckgs[cCores] = idPckg; 272 cCores++; 273 } 254 274 } 255 275 } … … 263 283 RTDECL(uint32_t) RTMpGetCurFrequency(RTCPUID idCpu) 264 284 { 265 int64_t kHz = RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", (int)idCpu); 266 if (kHz == -1) 285 int64_t kHz = 0; 286 int rc = RTLinuxSysFsReadIntFile(0, &kHz, "devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", (int)idCpu); 287 if (RT_FAILURE(rc)) 267 288 { 268 289 /* … … 281 302 RTDECL(uint32_t) RTMpGetMaxFrequency(RTCPUID idCpu) 282 303 { 283 int64_t kHz = RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", (int)idCpu); 284 if (kHz == -1) 304 int64_t kHz = 0; 305 int rc = RTLinuxSysFsReadIntFile(0, &kHz, "devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", (int)idCpu); 306 if (RT_FAILURE(rc)) 285 307 { 286 308 /* -
trunk/src/VBox/Runtime/r3/linux/sysfs.cpp
r57358 r60373 5 5 6 6 /* 7 * Copyright (C) 2006-201 5Oracle Corporation7 * Copyright (C) 2006-2016 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 30 30 *********************************************************************************************************************************/ 31 31 #define LOG_GROUP RTLOGGROUP_SYSTEM 32 #include <iprt/linux/sysfs.h>33 32 #include <iprt/assert.h> 34 33 #include <iprt/dir.h> 35 34 #include <iprt/err.h> 35 #include <iprt/file.h> 36 36 #include <iprt/fs.h> 37 37 #include <iprt/param.h> 38 38 #include <iprt/path.h> 39 39 #include <iprt/string.h> 40 #include <iprt/symlink.h> 41 42 #include <iprt/linux/sysfs.h> 40 43 41 44 #include <unistd.h> … … 46 49 #include <errno.h> 47 50 48 /** @todo r=bird: This whole API should be rewritten to use IPRT status codes.49 * using errno was a mistake and only results in horrible code. */50 51 51 52 … … 54 55 * prepending a prefix if the path is relative. 55 56 * 56 * @returns The number of characters returned, or an iprt error code on failure. 57 * 57 * @returns IPRT status code. 58 58 * @param pszPrefix The prefix to prepend if the path is relative. Must end 59 59 * in '/'. … … 65 65 * @param va The format args. 66 66 */ 67 static ssize_t rtLinuxConstructPathV(char *pszBuf, size_t cchBuf,67 static int rtLinuxConstructPathV(char *pszBuf, size_t cchBuf, 68 68 const char *pszPrefix, 69 69 const char *pszFormat, va_list va) … … 85 85 cch += cchPrefix; 86 86 } 87 return cch;87 return VINF_SUCCESS; 88 88 } 89 89 … … 93 93 * prepending a prefix if the path is relative. 94 94 * 95 * @returns The number of characters returned, or an iprt error code on failure. 96 * @note Unused. 97 * 95 * @returns IPRT status code. 98 96 * @param pszPrefix The prefix to prepend if the path is relative. Must end 99 97 * in '/'. … … 104 102 * @param ... The format args. 105 103 */ 106 static ssize_trtLinuxConstructPath(char *pszBuf, size_t cchBuf,107 const char *pszPrefix,108 const char *pszFormat, ...)104 DECLINLINE(int) rtLinuxConstructPath(char *pszBuf, size_t cchBuf, 105 const char *pszPrefix, 106 const char *pszFormat, ...) 109 107 { 110 108 va_list va; … … 120 118 * prepending "/sys/" if the path is relative. 121 119 * 122 * @returns The number of characters returned, or -1 and errno set to ERANGE on 123 * failure. 124 * 120 * @returns IPRT status code. 125 121 * @param pszBuf Where to write the path. Must be at least 126 122 * sizeof("/sys/") characters long … … 129 125 * @param va The format args. 130 126 */ 131 static ssize_t rtLinuxSysFsConstructPath(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va) 132 { 133 ssize_t rc = rtLinuxConstructPathV(pszBuf, cchBuf, "/sys/", pszFormat, va); 134 if (rc >= 0) 135 return rc; 136 errno = ERANGE; 137 return -1; 138 } 139 140 141 RTDECL(bool) RTLinuxSysFsExistsV(const char *pszFormat, va_list va) 127 DECLINLINE(int) rtLinuxSysFsConstructPath(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va) 128 { 129 return rtLinuxConstructPathV(pszBuf, cchBuf, "/sys/", pszFormat, va); 130 } 131 132 133 RTDECL(int) RTLinuxSysFsExistsExV(const char *pszFormat, va_list va) 142 134 { 143 135 int iSavedErrno = errno; … … 146 138 * Construct the filename and call stat. 147 139 */ 148 bool fRet = false;149 140 char szFilename[RTPATH_MAX]; 150 ssize_t rc = rtLinuxSysFsConstructPath(szFilename, sizeof(szFilename), pszFormat, va);151 if ( rc != -1)141 int rc = rtLinuxSysFsConstructPath(szFilename, sizeof(szFilename), pszFormat, va); 142 if (RT_SUCCESS(rc)) 152 143 { 153 144 struct stat st; 154 fRet = stat(szFilename, &st) == 0; 145 int rcStat = stat(szFilename, &st); 146 if (rcStat != 0) 147 rc = RTErrConvertFromErrno(errno); 155 148 } 156 149 157 150 errno = iSavedErrno; 151 return rc; 152 } 153 154 155 RTDECL(bool) RTLinuxSysFsExistsV(const char *pszFormat, va_list va) 156 { 157 return RT_SUCCESS(RTLinuxSysFsExistsExV(pszFormat, va)); 158 } 159 160 161 RTDECL(int) RTLinuxSysFsExistsEx(const char *pszFormat, ...) 162 { 163 va_list va; 164 va_start(va, pszFormat); 165 int rc = RTLinuxSysFsExistsExV(pszFormat, va); 166 va_end(va); 167 return rc; 168 } 169 170 171 RTDECL(bool) RTLinuxSysFsExists(const char *pszFormat, ...) 172 { 173 va_list va; 174 va_start(va, pszFormat); 175 bool fRet = RTLinuxSysFsExistsV(pszFormat, va); 176 va_end(va); 158 177 return fRet; 159 178 } 160 179 161 180 162 RTDECL(bool) RTLinuxSysFsExists(const char *pszFormat, ...) 163 { 164 va_list va; 165 va_start(va, pszFormat); 166 bool fRet = RTLinuxSysFsExistsV(pszFormat, va); 167 va_end(va); 168 return fRet; 169 } 170 171 172 RTDECL(int) RTLinuxSysFsOpenV(const char *pszFormat, va_list va) 181 RTDECL(int) RTLinuxSysFsOpenV(PRTFILE phFile, const char *pszFormat, va_list va) 173 182 { 174 183 /* … … 176 185 */ 177 186 char szFilename[RTPATH_MAX]; 178 ssize_t rc = rtLinuxSysFsConstructPath(szFilename, sizeof(szFilename), pszFormat, va); 179 if (rc != -1) 180 rc = open(szFilename, O_RDONLY, 0); 181 return rc; 182 } 183 184 185 RTDECL(int) RTLinuxSysFsOpen(const char *pszFormat, ...) 186 { 187 va_list va; 188 va_start(va, pszFormat); 189 int fd = RTLinuxSysFsOpenV(pszFormat, va); 190 va_end(va); 191 return fd; 192 } 193 194 195 RTDECL(void) RTLinuxSysFsClose(int fd) 196 { 197 int iSavedErrno = errno; 198 close(fd); 199 errno = iSavedErrno; 200 } 201 202 203 RTDECL(ssize_t) RTLinuxSysFsReadStr(int fd, char *pszBuf, size_t cchBuf) 187 int rc = rtLinuxSysFsConstructPath(szFilename, sizeof(szFilename), pszFormat, va); 188 if (RT_SUCCESS(rc)) 189 rc = RTFileOpen(phFile, szFilename, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE); 190 return rc; 191 } 192 193 194 RTDECL(int) RTLinuxSysFsOpen(PRTFILE phFile, const char *pszFormat, ...) 195 { 196 va_list va; 197 va_start(va, pszFormat); 198 int rc = RTLinuxSysFsOpenV(phFile, pszFormat, va); 199 va_end(va); 200 return rc; 201 } 202 203 204 RTDECL(int) RTLinuxSysFsReadStr(RTFILE hFile, char *pszBuf, size_t cchBuf, size_t *pcchRead) 204 205 { 205 206 Assert(cchBuf > 1); 206 ssize_t cchRead = read(fd, pszBuf, cchBuf - 1); 207 pszBuf[cchRead >= 0 ? cchRead : 0] = '\0'; 208 return cchRead; 209 } 210 211 212 RTDECL(int) RTLinuxSysFsReadFile(int fd, void *pvBuf, size_t cbBuf, size_t *pcbRead) 213 { 214 int rc; 215 ssize_t cbRead = read(fd, pvBuf, cbBuf); 216 if (cbRead >= 0) 207 size_t cchRead = 0; 208 int rc = RTFileRead(hFile, pszBuf, cchBuf - 1, &cchRead); 209 pszBuf[RT_SUCCESS(rc) ? cchRead : 0] = '\0'; 210 if ( RT_SUCCESS(rc) 211 && pcchRead) 212 *pcchRead = cchRead; 213 214 return rc; 215 } 216 217 218 RTDECL(int) RTLinuxSysFsReadFile(RTFILE hFile, void *pvBuf, size_t cbBuf, size_t *pcbRead) 219 { 220 int rc; 221 size_t cbRead = 0; 222 223 rc = RTFileRead(hFile, pvBuf, cbBuf, &cbRead); 224 if (RT_SUCCESS(rc)) 217 225 { 218 226 if (pcbRead) 219 227 *pcbRead = cbRead; 220 if ( (size_t)cbRead < cbBuf)228 if (cbRead < cbBuf) 221 229 rc = VINF_SUCCESS; 222 230 else 223 231 { 224 232 /* Check for EOF */ 225 char ch; 226 off_t off = lseek(fd, 0, SEEK_CUR); 227 ssize_t cbRead2 = read(fd, &ch, 1); 228 if (cbRead2 == 0) 229 rc = VINF_SUCCESS; 230 else if (cbRead2 > 0) 233 char ch; 234 uint64_t offCur = 0; 235 uint64_t offEnd = 0; 236 rc = RTFileSeek(hFile, 0, RTFILE_SEEK_CURRENT, &offCur); 237 if (RT_SUCCESS(rc)) 238 rc = RTFileSeek(hFile, 0, RTFILE_SEEK_END, &offEnd); 239 if ( RT_SUCCESS(rc) 240 && offEnd > offCur) 241 rc = VERR_BUFFER_OVERFLOW; 242 } 243 } 244 245 return rc; 246 } 247 248 249 RTDECL(int) RTLinuxSysFsReadIntFileV(unsigned uBase, int64_t *pi64, const char *pszFormat, va_list va) 250 { 251 RTFILE hFile; 252 253 AssertPtrReturn(pi64, VERR_INVALID_POINTER); 254 255 int rc = RTLinuxSysFsOpenV(&hFile, pszFormat, va); 256 if (RT_SUCCESS(rc)) 257 { 258 char szNum[128]; 259 size_t cchNum; 260 rc = RTLinuxSysFsReadStr(hFile, szNum, sizeof(szNum), &cchNum); 261 if (RT_SUCCESS(rc)) 262 { 263 if (cchNum > 0) 231 264 { 232 lseek(fd, off, SEEK_SET); 233 rc = VERR_BUFFER_OVERFLOW; 265 int64_t i64Ret = -1; 266 rc = RTStrToInt64Ex(szNum, NULL, uBase, &i64Ret); 267 if (RT_SUCCESS(rc)) 268 *pi64 = i64Ret; 234 269 } 235 270 else 236 rc = RTErrConvertFromErrno(errno); 237 } 238 } 239 else 240 rc = RTErrConvertFromErrno(errno); 241 return rc; 242 } 243 244 245 RTDECL(int64_t) RTLinuxSysFsReadIntFileV(unsigned uBase, const char *pszFormat, va_list va) 246 { 247 int fd = RTLinuxSysFsOpenV(pszFormat, va); 248 if (fd == -1) 249 return -1; 250 251 int64_t i64Ret = -1; 252 char szNum[128]; 253 ssize_t cchNum = RTLinuxSysFsReadStr(fd, szNum, sizeof(szNum)); 254 if (cchNum > 0) 255 { 256 int rc = RTStrToInt64Ex(szNum, NULL, uBase, &i64Ret); 257 if (RT_FAILURE(rc)) 258 { 259 i64Ret = -1; 260 errno = -ETXTBSY; /* just something that won't happen at read / open. */ 261 } 262 } 263 else if (cchNum == 0) 264 errno = -ETXTBSY; /* just something that won't happen at read / open. */ 265 266 RTLinuxSysFsClose(fd); 267 return i64Ret; 268 } 269 270 271 RTDECL(int64_t) RTLinuxSysFsReadIntFile(unsigned uBase, const char *pszFormat, ...) 272 { 273 va_list va; 274 va_start(va, pszFormat); 275 int64_t i64Ret = RTLinuxSysFsReadIntFileV(uBase, pszFormat, va); 276 va_end(va); 277 return i64Ret; 278 } 279 280 281 RTDECL(dev_t) RTLinuxSysFsReadDevNumFileV(const char *pszFormat, va_list va) 282 { 283 int fd = RTLinuxSysFsOpenV(pszFormat, va); 284 if (fd == -1) 285 return 0; 286 287 dev_t DevNum = 0; 288 char szNum[128]; 289 ssize_t cchNum = RTLinuxSysFsReadStr(fd, szNum, sizeof(szNum)); 290 if (cchNum > 0) 291 { 292 uint32_t u32Maj = 0; 293 uint32_t u32Min = 0; 294 char *pszNext = NULL; 295 int rc = RTStrToUInt32Ex(szNum, &pszNext, 10, &u32Maj); 296 if (RT_FAILURE(rc) || (rc != VWRN_TRAILING_CHARS) || (*pszNext != ':')) 297 errno = EINVAL; 298 else 299 { 300 rc = RTStrToUInt32Ex(pszNext + 1, NULL, 10, &u32Min); 301 if ( rc != VINF_SUCCESS 302 && rc != VWRN_TRAILING_CHARS 303 && rc != VWRN_TRAILING_SPACES) 304 errno = EINVAL; 271 rc = VERR_INVALID_PARAMETER; 272 } 273 274 RTFileClose(hFile); 275 } 276 277 return rc; 278 } 279 280 281 RTDECL(int) RTLinuxSysFsReadIntFile(unsigned uBase, int64_t *pi64, const char *pszFormat, ...) 282 { 283 va_list va; 284 va_start(va, pszFormat); 285 int rc = RTLinuxSysFsReadIntFileV(uBase, pi64, pszFormat, va); 286 va_end(va); 287 return rc; 288 } 289 290 291 RTDECL(int) RTLinuxSysFsReadDevNumFileV(dev_t *pDevNum, const char *pszFormat, va_list va) 292 { 293 RTFILE hFile; 294 295 AssertPtrReturn(pDevNum, VERR_INVALID_POINTER); 296 297 int rc = RTLinuxSysFsOpenV(&hFile, pszFormat, va); 298 if (RT_SUCCESS(rc)) 299 { 300 size_t cchNum = 0; 301 char szNum[128]; 302 rc = RTLinuxSysFsReadStr(hFile, szNum, sizeof(szNum), &cchNum); 303 if (RT_SUCCESS(rc)) 304 { 305 if (cchNum > 0) 306 { 307 uint32_t u32Maj = 0; 308 uint32_t u32Min = 0; 309 char *pszNext = NULL; 310 rc = RTStrToUInt32Ex(szNum, &pszNext, 10, &u32Maj); 311 if (RT_FAILURE(rc) || (rc != VWRN_TRAILING_CHARS) || (*pszNext != ':')) 312 rc = VERR_INVALID_PARAMETER; 313 else 314 { 315 rc = RTStrToUInt32Ex(pszNext + 1, NULL, 10, &u32Min); 316 if ( rc != VINF_SUCCESS 317 && rc != VWRN_TRAILING_CHARS 318 && rc != VWRN_TRAILING_SPACES) 319 rc = VERR_INVALID_PARAMETER; 320 else 321 *pDevNum = makedev(u32Maj, u32Min); 322 } 323 } 305 324 else 306 { 307 errno = 0; 308 DevNum = makedev(u32Maj, u32Min); 309 } 310 } 311 } 312 else if (cchNum == 0) 313 errno = EINVAL; 314 315 RTLinuxSysFsClose(fd); 316 return DevNum; 317 } 318 319 320 RTDECL(dev_t) RTLinuxSysFsReadDevNumFile(const char *pszFormat, ...) 321 { 322 va_list va; 323 va_start(va, pszFormat); 324 dev_t DevNum = RTLinuxSysFsReadDevNumFileV(pszFormat, va); 325 va_end(va); 326 return DevNum; 327 } 328 329 330 RTDECL(ssize_t) RTLinuxSysFsReadStrFileV(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va) 331 { 332 int fd = RTLinuxSysFsOpenV(pszFormat, va); 333 if (fd == -1) 334 return -1; 335 336 ssize_t cchRet = RTLinuxSysFsReadStr(fd, pszBuf, cchBuf); 337 RTLinuxSysFsClose(fd); 338 if (cchRet > 0) 339 { 340 char *pchNewLine = (char *)memchr(pszBuf, '\n', cchRet); 341 if (pchNewLine) 342 *pchNewLine = '\0'; 343 } 344 return cchRet; 345 } 346 347 348 RTDECL(ssize_t) RTLinuxSysFsReadStrFile(char *pszBuf, size_t cchBuf, const char *pszFormat, ...) 349 { 350 va_list va; 351 va_start(va, pszFormat); 352 ssize_t cchRet = RTLinuxSysFsReadStrFileV(pszBuf, cchBuf, pszFormat, va); 353 va_end(va); 354 return cchRet; 355 } 356 357 358 RTDECL(ssize_t) RTLinuxSysFsGetLinkDestV(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va) 359 { 360 AssertReturnStmt(cchBuf >= 2, errno = EINVAL, -1); 325 rc = VERR_INVALID_PARAMETER; 326 } 327 328 RTFileClose(hFile); 329 } 330 331 return rc; 332 } 333 334 335 RTDECL(int) RTLinuxSysFsReadDevNumFile(dev_t *pDevNum, const char *pszFormat, ...) 336 { 337 va_list va; 338 va_start(va, pszFormat); 339 int rc = RTLinuxSysFsReadDevNumFileV(pDevNum, pszFormat, va); 340 va_end(va); 341 return rc; 342 } 343 344 345 RTDECL(int) RTLinuxSysFsReadStrFileV(char *pszBuf, size_t cchBuf, size_t *pcchRead, const char *pszFormat, va_list va) 346 { 347 RTFILE hFile; 348 349 AssertPtrReturn(pszBuf, VERR_INVALID_POINTER); 350 351 int rc = RTLinuxSysFsOpenV(&hFile, pszFormat, va); 352 if (RT_SUCCESS(rc)) 353 { 354 size_t cchRead = 0; 355 rc = RTLinuxSysFsReadStr(hFile, pszBuf, cchBuf, &cchRead); 356 RTFileClose(hFile); 357 if ( RT_SUCCESS(rc) 358 && cchRead > 0) 359 { 360 char *pchNewLine = (char *)memchr(pszBuf, '\n', cchRead); 361 if (pchNewLine) 362 *pchNewLine = '\0'; 363 } 364 365 if (pcchRead) 366 *pcchRead = cchRead; 367 } 368 return rc; 369 } 370 371 372 RTDECL(int) RTLinuxSysFsReadStrFile(char *pszBuf, size_t cchBuf, size_t *pcchRead, const char *pszFormat, ...) 373 { 374 va_list va; 375 va_start(va, pszFormat); 376 int rc = RTLinuxSysFsReadStrFileV(pszBuf, cchBuf, pcchRead, pszFormat, va); 377 va_end(va); 378 return rc; 379 } 380 381 382 RTDECL(int) RTLinuxSysFsGetLinkDestV(char *pszBuf, size_t cchBuf, size_t *pchBuf, const char *pszFormat, va_list va) 383 { 384 AssertReturn(cchBuf >= 2, VERR_INVALID_PARAMETER); 361 385 362 386 /* … … 365 389 char szFilename[RTPATH_MAX]; 366 390 int rc = rtLinuxSysFsConstructPath(szFilename, sizeof(szFilename), pszFormat, va); 367 if (rc == -1) 368 return -1; 369 370 char szLink[RTPATH_MAX]; 371 rc = readlink(szFilename, szLink, sizeof(szLink)); 372 if (rc == -1) 373 return -1; 374 if ((size_t)rc > sizeof(szLink) - 1) 375 { 376 errno = ERANGE; 377 return -1; 378 } 379 szLink[rc] = '\0'; /* readlink fun. */ 380 381 /* 382 * Extract the file name component and copy it into the return buffer. 383 */ 384 size_t cchName; 385 const char *pszName = RTPathFilename(szLink); 386 if (pszName) 387 { 388 cchName = strlen(pszName); /* = &szLink[rc] - pszName; */ 389 if (cchName >= cchBuf) 390 { 391 errno = ERANGE; 392 return -1; 393 } 394 memcpy(pszBuf, pszName, cchName + 1); 395 } 396 else 397 { 398 *pszBuf = '\0'; 399 cchName = 0; 400 } 401 return cchName; 402 } 403 404 405 RTDECL(ssize_t) RTLinuxSysFsGetLinkDest(char *pszBuf, size_t cchBuf, const char *pszFormat, ...) 406 { 407 va_list va; 408 va_start(va, pszFormat); 409 int rc = RTLinuxSysFsGetLinkDestV(pszBuf, cchBuf, pszFormat, va); 410 va_end(va); 411 return rc; 412 } 413 414 415 RTDECL(ssize_t) RTLinuxCheckDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf, 416 size_t cchBuf, const char *pszPattern, 417 va_list va) 418 { 419 char szFilename[RTPATH_MAX]; 420 int rc = VINF_TRY_AGAIN; 421 391 if (RT_SUCCESS(rc)) 392 { 393 char szLink[RTPATH_MAX]; 394 rc = RTSymlinkRead(szFilename, szLink, sizeof(szLink), 0); 395 if (RT_SUCCESS(rc)) 396 { 397 /* 398 * Extract the file name component and copy it into the return buffer. 399 */ 400 size_t cchName; 401 const char *pszName = RTPathFilename(szLink); 402 if (pszName) 403 { 404 cchName = strlen(pszName); 405 if (cchName < cchBuf) 406 memcpy(pszBuf, pszName, cchName + 1); 407 else 408 rc = VERR_BUFFER_OVERFLOW; 409 } 410 else 411 { 412 *pszBuf = '\0'; 413 cchName = 0; 414 } 415 416 if (pchBuf) 417 *pchBuf = cchName; 418 } 419 } 420 421 return rc; 422 } 423 424 425 RTDECL(int) RTLinuxSysFsGetLinkDest(char *pszBuf, size_t cchBuf, size_t *pchBuf, const char *pszFormat, ...) 426 { 427 va_list va; 428 va_start(va, pszFormat); 429 int rc = RTLinuxSysFsGetLinkDestV(pszBuf, cchBuf, pchBuf, pszFormat, va); 430 va_end(va); 431 return rc; 432 } 433 434 435 RTDECL(int) RTLinuxCheckDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf, 436 size_t cchBuf, const char *pszPattern, 437 va_list va) 438 { 422 439 AssertReturn(cchBuf >= 2, VERR_INVALID_PARAMETER); 423 440 AssertReturn( fMode == RTFS_TYPE_DEV_CHAR 424 441 || fMode == RTFS_TYPE_DEV_BLOCK, 425 442 VERR_INVALID_PARAMETER); 426 if (pszPattern) 427 { 428 /* 429 * Construct the filename and read the link. 430 */ 431 rc = rtLinuxConstructPathV(szFilename, sizeof(szFilename), "/dev/", 443 AssertPtrReturn(pszPattern, VERR_INVALID_PARAMETER); 444 445 /* 446 * Construct the filename and read the link. 447 */ 448 char szFilename[RTPATH_MAX]; 449 int rc = rtLinuxConstructPathV(szFilename, sizeof(szFilename), "/dev/", 432 450 pszPattern, va); 433 if (rc > 0) 434 { 435 RTFSOBJINFO Info; 436 rc = RTPathQueryInfo(szFilename, &Info, RTFSOBJATTRADD_UNIX); 437 if ( rc == VERR_PATH_NOT_FOUND 438 || ( RT_SUCCESS(rc) 439 && ( Info.Attr.u.Unix.Device != DevNum 440 || (Info.Attr.fMode & RTFS_TYPE_MASK) != fMode))) 441 rc = VERR_FILE_NOT_FOUND; 442 } 443 } 444 445 if (RT_SUCCESS(rc)) 446 { 447 size_t cchPath = strlen(szFilename); 448 if (cchPath >= cchBuf) 449 return VERR_BUFFER_OVERFLOW; 450 memcpy(pszBuf, szFilename, cchPath + 1); 451 return cchPath; 452 } 453 return rc; 454 } 455 456 457 /** @todo Do we really need to return the string length? If the caller is 458 * interested (the current ones aren't) they can check themselves. */ 459 RTDECL(ssize_t) RTLinuxCheckDevicePath(dev_t DevNum, RTFMODE fMode, char *pszBuf, 460 size_t cchBuf, const char *pszPattern, 461 ...) 451 if (RT_SUCCESS(rc)) 452 { 453 RTFSOBJINFO Info; 454 rc = RTPathQueryInfo(szFilename, &Info, RTFSOBJATTRADD_UNIX); 455 if ( rc == VERR_PATH_NOT_FOUND 456 || ( RT_SUCCESS(rc) 457 && ( Info.Attr.u.Unix.Device != DevNum 458 || (Info.Attr.fMode & RTFS_TYPE_MASK) != fMode))) 459 rc = VERR_FILE_NOT_FOUND; 460 461 if (RT_SUCCESS(rc)) 462 { 463 size_t cchPath = strlen(szFilename); 464 if (cchPath < cchBuf) 465 memcpy(pszBuf, szFilename, cchPath + 1); 466 else 467 rc = VERR_BUFFER_OVERFLOW; 468 } 469 } 470 471 return rc; 472 } 473 474 475 RTDECL(int) RTLinuxCheckDevicePath(dev_t DevNum, RTFMODE fMode, char *pszBuf, 476 size_t cchBuf, const char *pszPattern, 477 ...) 462 478 { 463 479 va_list va;
Note:
See TracChangeset
for help on using the changeset viewer.