Some sysfs files contain either string representation of a bitmap or just a newline character. An example of such file is: /sys/devices/system/cpu/isolated. Our current implementation of virFileReadValueBitmap() fails in the latter case, unfortunately. Introduce a slightly modified version that accepts empty files. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/util/virfile.c | 81 ++++++++++++++++++++++++++++++---------- src/util/virfile.h | 2 + 3 files changed, 65 insertions(+), 19 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0ba6183010..2c7e4b45d3 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2360,6 +2360,7 @@ virFileReadHeaderFD; virFileReadHeaderQuiet; virFileReadLimFD; virFileReadValueBitmap; +virFileReadValueBitmapAllowEmpty; virFileReadValueInt; virFileReadValueScaledInt; virFileReadValueString; diff --git a/src/util/virfile.c b/src/util/virfile.c index deaf4555fd..c769f7d650 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -4365,26 +4365,12 @@ virFileReadValueScaledInt(unsigned long long *value, const char *format, ...) * used for small, interface-like files, so it should not be huge (subjective) */ #define VIR_FILE_READ_VALUE_STRING_MAX 4096 -/** - * virFileReadValueBitmap: - * @value: pointer to virBitmap * to be allocated and filled in with the value - * @format, ...: file to read from - * - * Read int from @format and put it into @value. - * - * Return -2 for non-existing file, -1 on other errors and 0 if everything went - * fine. - */ -int -virFileReadValueBitmap(virBitmap **value, const char *format, ...) +static int +virFileReadValueBitmapImpl(virBitmap **value, + const char *path, + bool allowEmpty) { g_autofree char *str = NULL; - g_autofree char *path = NULL; - va_list ap; - - va_start(ap, format); - path = g_strdup_vprintf(format, ap); - va_end(ap); if (!virFileExists(path)) return -2; @@ -4394,13 +4380,70 @@ virFileReadValueBitmap(virBitmap **value, const char *format, ...) virStringTrimOptionalNewline(str); - *value = virBitmapParseUnlimited(str); + if (allowEmpty) { + *value = virBitmapParseUnlimitedAllowEmpty(str); + } else { + *value = virBitmapParseUnlimited(str); + } + if (!*value) return -1; return 0; } + +/** + * virFileReadValueBitmap: + * @value: pointer to virBitmap * to be allocated and filled in with the value + * @format, ...: file to read from + * + * Read int from @format and put it into @value. + * + * Returns: -2 for non-existing file, + * -1 on other errors (with error reported), + * 0 otherwise. + */ +int +virFileReadValueBitmap(virBitmap **value, const char *format, ...) +{ + g_autofree char *path = NULL; + va_list ap; + + va_start(ap, format); + path = g_strdup_vprintf(format, ap); + va_end(ap); + + return virFileReadValueBitmapImpl(value, path, false); +} + + +/** + * virFileReadValueBitmapAllowEmpty: + * @value: pointer to virBitmap * to be allocated and filled in with the value + * @format, ...: file to read from + * + * Just like virFileReadValueBitmap(), except if the file is empty or contains + * nothing but spaces an empty bitmap is returned instead of an error. + * + * Returns: -2 for non-existing file, + * -1 on other errors (with error reported), + * 0 otherwise. + */ +int +virFileReadValueBitmapAllowEmpty(virBitmap **value, const char *format, ...) +{ + g_autofree char *path = NULL; + va_list ap; + + va_start(ap, format); + path = g_strdup_vprintf(format, ap); + va_end(ap); + + return virFileReadValueBitmapImpl(value, path, true); +} + + /** * virFileReadValueString: * @value: pointer to char * to be allocated and filled in with the value diff --git a/src/util/virfile.h b/src/util/virfile.h index 56fe309bce..7df3fcb840 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -354,6 +354,8 @@ int virFileReadValueUllongQuiet(unsigned long long *value, const char *format, . G_GNUC_PRINTF(2, 3); int virFileReadValueBitmap(virBitmap **value, const char *format, ...) G_GNUC_PRINTF(2, 3); +int virFileReadValueBitmapAllowEmpty(virBitmap **value, const char *format, ...) + G_GNUC_PRINTF(2, 3); int virFileReadValueScaledInt(unsigned long long *value, const char *format, ...) G_GNUC_PRINTF(2, 3); int virFileReadValueString(char **value, const char *format, ...) -- 2.43.2 _______________________________________________ Devel mailing list -- devel@xxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx