From: Natanael Copa <ncopa@xxxxxxxxxxxxxxx> Introduce a wrapper for readdir. This helps us make sure that we always set errno before calling readdir and it will make sure errors are properly logged. Signed-off-by: Natanael Copa <ncopa@xxxxxxxxxxxxxxx> Signed-off-by: Eric Blake <eblake@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/util/virfile.c | 33 +++++++++++++++++++++++++++++++++ src/util/virfile.h | 4 ++++ 3 files changed, 38 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5788468..8bbe6e7 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1222,6 +1222,7 @@ safewrite; safezero; virBuildPathInternal; virDirCreate; +virDirRead; virFileAbsPath; virFileAccessibleAs; virFileActivateDirOverride; diff --git a/src/util/virfile.c b/src/util/virfile.c index da4e0a0..3481124 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -2391,6 +2391,39 @@ virDirCreate(const char *path ATTRIBUTE_UNUSED, } #endif /* WIN32 */ +/** + * virDirRead: + * @dirp: directory to read + * @end: output one entry + * @name: if non-NULL, the name related to @dirp for use in error reporting + * + * Wrapper around readdir. Typical usage: + * struct dirent ent; + * int value; + * DIR *dir; + * if (!(dir = opendir(name))) + * goto error; + * while ((value = virDirRead(dir, &ent, name)) > 0) + * process ent; + * if (value < 0) + * goto error; + * + * Returns -1 on error, with error already reported if @name was + * supplied. On success, returns 1 for entry read, 0 for end-of-dir. + */ +int virDirRead(DIR *dirp, struct dirent **ent, const char *name) +{ + errno = 0; + *ent = readdir(dirp); + if (!*ent && errno) { + if (name) + virReportSystemError(errno, _("Unable to read directory '%s'"), + name); + return -1; + } + return !!*ent; +} + static int virFileMakePathHelper(char *path, mode_t mode) { diff --git a/src/util/virfile.h b/src/util/virfile.h index 5d0d699..12bcb22 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -27,6 +27,7 @@ # define __VIR_FILE_H_ # include <stdio.h> +# include <dirent.h> # include "internal.h" # include "virstoragefile.h" @@ -225,6 +226,9 @@ enum { }; int virDirCreate(const char *path, mode_t mode, uid_t uid, gid_t gid, unsigned int flags) ATTRIBUTE_RETURN_CHECK; +int virDirRead(DIR *dirp, struct dirent **ent, const char *dirname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + int virFileMakePath(const char *path) ATTRIBUTE_RETURN_CHECK; int virFileMakePathWithMode(const char *path, mode_t mode) ATTRIBUTE_RETURN_CHECK; -- 1.9.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list