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@xxxxxxxxxx> --- 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