/** * Constructs the path of a sysfs file from the format parameters passed, * prepending "/sys/" if the path is relative. * * @returns The number of characters returned, or -1 and errno set to ERANGE on * failure. * * @param pszBuf Where to write the path. Must be at least * sizeof("/sys/") characters long * @param cchBuf The size of the buffer pointed to by @a pszBuf. * @param pszFormat The name format, either absolute or relative to "/sys/". * @param va The format args. */ static ssize_t rtLinuxSysFsConstructPath(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va) { ssize_t rc = rtLinuxConstructPathV(pszBuf, cchBuf, "/sys/", pszFormat, va); if (rc >= 0) return rc; errno = ERANGE; return -1; }
/** * Constructs the path of a sysfs file from the format parameters passed, * prepending a prefix if the path is relative. * * @returns The number of characters returned, or -1 and errno set to ERANGE on * failure. * * @param pszPrefix The prefix to prepend if the path is relative. Must end * in '/'. * @param pszBuf Where to write the path. Must be at least * sizeof(@a pszPrefix) characters long * @param cchBuf The size of the buffer pointed to by @a pszBuf. * @param pszFormat The name format, either absolute or relative to "/sys/". * @param ... The format args. */ static ssize_t rtLinuxConstructPath(char *pszBuf, size_t cchBuf, const char *pszPrefix, const char *pszFormat, ...) { va_list va; va_start(va, pszFormat); int rc = rtLinuxConstructPathV(pszBuf, cchBuf, pszPrefix, pszFormat, va); va_end(va); return rc; }
RTDECL(ssize_t) RTLinuxFindDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf, size_t cchBuf, const char *pszSuggestion, va_list va) { AssertReturnStmt(cchBuf >= 2, errno = EINVAL, -1); AssertReturnStmt( fMode == RTFS_TYPE_DEV_CHAR || fMode == RTFS_TYPE_DEV_BLOCK, errno = EINVAL, -1); if (pszSuggestion) { /* * Construct the filename and read the link. */ char szFilename[RTPATH_MAX]; int rc = rtLinuxConstructPathV(szFilename, sizeof(szFilename), "/dev/", pszSuggestion, va); if (rc == -1) return -1; /* * Check whether the caller's suggestion was right. */ RTFSOBJINFO Info; rc = RTPathQueryInfo(szFilename, &Info, RTFSOBJATTRADD_UNIX); if ( RT_SUCCESS(rc) && Info.Attr.u.Unix.Device == DevNum && (Info.Attr.fMode & RTFS_TYPE_MASK) == fMode) { size_t cchPath = strlen(szFilename); if (cchPath >= cchBuf) { errno = EOVERFLOW; return -1; } memcpy(pszBuf, szFilename, cchPath + 1); return cchPath; } /* The suggestion was wrong, fall back on the brute force attack. */ } return rtLinuxFindDevicePathRecursive(DevNum, fMode, "/dev/", pszBuf, cchBuf); }
RTDECL(ssize_t) RTLinuxCheckDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf, size_t cchBuf, const char *pszPattern, va_list va) { char szFilename[RTPATH_MAX]; int rc = VINF_TRY_AGAIN; AssertReturn(cchBuf >= 2, VERR_INVALID_PARAMETER); AssertReturn( fMode == RTFS_TYPE_DEV_CHAR || fMode == RTFS_TYPE_DEV_BLOCK, VERR_INVALID_PARAMETER); if (pszPattern) { /* * Construct the filename and read the link. */ rc = rtLinuxConstructPathV(szFilename, sizeof(szFilename), "/dev/", pszPattern, va); if (rc > 0) { RTFSOBJINFO Info; rc = RTPathQueryInfo(szFilename, &Info, RTFSOBJATTRADD_UNIX); if ( rc == VERR_PATH_NOT_FOUND || ( RT_SUCCESS(rc) && ( Info.Attr.u.Unix.Device != DevNum || (Info.Attr.fMode & RTFS_TYPE_MASK) != fMode))) rc = VERR_FILE_NOT_FOUND; } } if (RT_SUCCESS(rc)) { size_t cchPath = strlen(szFilename); if (cchPath >= cchBuf) return VERR_BUFFER_OVERFLOW; memcpy(pszBuf, szFilename, cchPath + 1); return cchPath; } return rc; }
/** * Constructs the path of a sysfs file from the format parameters passed, * prepending "/sys/" if the path is relative. * * @returns The number of characters returned, or -1 and errno set to ERANGE on * failure. * * @param pszBuf Where to write the path. Must be at least * sizeof("/sys/") characters long * @param cchBuf The size of the buffer pointed to by @a pszBuf. * @param pszFormat The name format, either absolute or relative to "/sys/". * @param va The format args. */ static ssize_t rtLinuxSysFsConstructPath(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va) { return rtLinuxConstructPathV(pszBuf, cchBuf, "/sys/", pszFormat, va); }