There might be cases where we want to know whether given
directory is empty or not. Introduce a helper for that:
virDirIsEmpty().
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virfile.c | 39 +++++++++++++++++++++++++++++++++++++++
src/util/virfile.h | 3 +++
3 files changed, 43 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3071dec13a..da60c965dd 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2271,6 +2271,7 @@ safezero;
virBuildPathInternal;
virDirClose;
virDirCreate;
+virDirIsEmpty;
virDirOpen;
virDirOpenIfExists;
virDirOpenQuiet;
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 6b4d4c3522..7c44a2a963 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -3036,6 +3036,45 @@ void virDirClose(DIR *dirp)
closedir(dirp); /* exempt from syntax-check */
}
+/**
+ * virDirIsEmpty:
+ * @path: path to the directory
+ * @hidden: whether hidden files matter
+ *
+ * Check whether given directory (@path) is empty, i.e. it
+ * contains just the usual entries '.' and '..'. Hidden files are
+ * ignored unless @hidden is true. IOW, a directory containing
+ * nothing but hidden files is considered empty if @hidden is
+ * false and not empty if @hidden is true.
+ *
+ * Returns: 1 if the directory is empty,
+ * 0 if the directory is not empty,
+ * -1 otherwise (no error reported).
+ */
+int virDirIsEmpty(const char *path,
+ bool hidden)
+{
+ g_autoptr(DIR) dir = NULL;
+ struct dirent *ent;
+ int direrr;
+
+ if (virDirOpenQuiet(&dir, path) < 0)
+ return -1;
+
+ while ((direrr = virDirRead(dir, &ent, NULL)) > 0) {
+ /* virDirRead() skips over '.' and '..' so here we have
+ * actual directory entry. */
+ if (!hidden ||
+ (hidden && ent->d_name[0] != '.'))
+ return 0;
+ }
+
+ if (direrr < 0)
+ return -1;
+
+ return 1;
+}
+
/*
* virFileChownFiles:
diff --git a/src/util/virfile.h b/src/util/virfile.h
index 6a14173625..b75a7cc53b 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -283,6 +283,9 @@ int virDirRead(DIR *dirp, struct dirent **ent, const char *dirname)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT;
void virDirClose(DIR *dirp);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(DIR, virDirClose);
+int virDirIsEmpty(const char *path,
+ bool hidden)
+ ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT;
int virFileMakeParentPath(const char *path) G_GNUC_WARN_UNUSED_RESULT;
--
2.41.0