diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 00efc29699..0f5a96d123 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1629,6 +1629,9 @@ virFileReadBufQuiet; virFileReadHeaderFD; virFileReadLimFD; virFileReadLink; +virFileReadValueBitmap; +virFileReadValueInt; +virFileReadValueUint; virFileRelLinkPointsTo; virFileRemove; virFileRemoveLastComponent; diff --git a/src/util/virfile.c b/src/util/virfile.c index 41cdca953b..a91c2c3495 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -65,6 +65,7 @@ #endif #include "configmake.h" +#include "intprops.h" #include "viralloc.h" #include "vircommand.h" #include "virerror.h" @@ -3794,3 +3795,116 @@ virFileComparePaths(const char *p1, const char *p2) VIR_FREE(res2); return ret; } + + +/** + * virFileReadValueInt: + * @path: file to read from + * @value: pointer to int to be filled in with the value + * + * Read int from @path and put it into @value. + * + * Return -2 for non-existing file, -1 on other errors and 0 if everything went + * fine. + */ +int +virFileReadValueInt(const char *path, int *value) +{ + char *str = NULL; + char *endp = NULL; + + if (!virFileExists(path)) + return -2; + + if (virFileReadAll(path, INT_STRLEN_BOUND(*value), &str) < 0) + return -1; + + if (virStrToLong_i(str, &endp, 10, value) < 0 || + (endp && !c_isspace(*endp))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid integer value '%s' in file '%s'"), + str, path); + return -1; + } + + VIR_FREE(str); + + return 0; +} + + +/** + * virFileReadValueUint: + * @path: file to read from + * @value: pointer to unsigned int to be filled in with the value + * + * Read int from @path and put it into @value. + * + * Return -2 for non-existing file, -1 on other errors and 0 if everything went + * fine. + */ +int +virFileReadValueUint(const char *path, unsigned int *value) +{ + char *str = NULL; + char *endp = NULL; + + if (!virFileExists(path)) + return -2; + + if (virFileReadAll(path, INT_STRLEN_BOUND(*value), &str) < 0) + return -1; + + if (virStrToLong_uip(str, &endp, 10, value) < 0 || + (endp && !c_isspace(*endp))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid unsigned integer value '%s' in file '%s'"), + str, path); + return -1; + } + + VIR_FREE(str); + + return 0; +} + +/** + * virFileReadValueBitmap: + * @path: file to read from + * @value: double pointer to virBitmap to be allocated and filled in with the + * value + * + * Read int from @path and put it into @value. + * + * Return -2 for non-existing file, -1 on other errors and 0 if everything went + * fine. + */ +int +virFileReadValueBitmap(const char *path, + int maxlen, + virBitmapPtr *value) +{ + char *buf = NULL; + int ret = -1; + char *tmp = NULL; + + if (!virFileExists(path)) + return -2; + + if (virFileReadAll(path, maxlen, &buf) < 0) + goto cleanup; + + /* trim optinoal newline at the end */ + tmp = buf + strlen(buf) - 1; + if (*tmp == '\n') + *tmp = '\0'; + + *value = virBitmapParseUnlimited(buf); + if (!*value) + goto cleanup; + + ret = 0; + cleanup: + VIR_FREE(buf); + return ret; +} diff --git a/src/util/virfile.h b/src/util/virfile.h index b29feeeb1d..ba1c57c06a 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -30,6 +30,7 @@ # include # include "internal.h" +# include "virbitmap.h" # include "virstoragefile.h" typedef enum { @@ -334,4 +335,9 @@ int virFileCopyACLs(const char *src, const char *dst); int virFileComparePaths(const char *p1, const char *p2); + +int virFileReadValueInt(const char *path, int *value); +int virFileReadValueUint(const char *path, unsigned int *value); +int virFileReadValueBitmap(const char *path, int maxlen, virBitmapPtr *value); + #endif /* __VIR_FILE_H */