[libvirt] [PATCHv2 1/7] util: introduce virDirRead wrapper for readdir

Eric Blake eblake at redhat.com
Sat Apr 26 13:18:14 UTC 2014


From: Natanael Copa <ncopa at 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 at alpinelinux.org>
Signed-off-by: Eric Blake <eblake at 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




More information about the libvir-list mailing list