From: Natanael Copa <ncopa(a)alpinelinux.org>
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(a)alpinelinux.org>
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
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