[libvirt] [PATCH v3 01/16] Introduce a virFileDeleteTree method

Daniel P. Berrange berrange at redhat.com
Wed Apr 10 10:08:10 UTC 2013


From: "Daniel P. Berrange" <berrange at redhat.com>

Introduce a method virFileDeleteTree for recursively deleting
an entire directory tree

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/libvirt_private.syms |  1 +
 src/util/virfile.c       | 78 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virfile.h       |  2 ++
 3 files changed, 81 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 449696d..af13e50 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1259,6 +1259,7 @@ virEventPollUpdateTimeout;
 
 # util/virfile.h
 virFileClose;
+virFileDeleteTree;
 virFileDirectFdFlag;
 virFileFclose;
 virFileFdopen;
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 4a9fa81..4d338e1 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -644,3 +644,81 @@ int virFileLoopDeviceAssociate(const char *file,
 }
 
 #endif /* __linux__ */
+
+
+/**
+ * virFileDeleteTree:
+ *
+ * Recursively deletes all files / directories
+ * starting from the directory @dir. Does not
+ * follow symlinks
+ */
+int virFileDeleteTree(const char *dir)
+{
+    DIR *dh = opendir(dir);
+    struct dirent *de;
+    char *filepath = NULL;
+    int ret = -1;
+
+    if (!dh) {
+        virReportSystemError(errno, _("Cannot open dir '%s'"),
+                             dir);
+        return -1;
+    }
+
+    errno = 0;
+    while ((de = readdir(dh)) != NULL) {
+        struct stat sb;
+
+        if (STREQ(de->d_name, ".") ||
+            STREQ(de->d_name, ".."))
+            continue;
+
+        if (virAsprintf(&filepath, "%s/%s",
+                        dir, de->d_name) < 0) {
+            virReportOOMError();
+            goto cleanup;
+        }
+
+        if (lstat(filepath, &sb) < 0) {
+            virReportSystemError(errno, _("Cannot access '%s'"),
+                                 filepath);
+            goto cleanup;
+        }
+
+        if (S_ISDIR(sb.st_mode)) {
+            if (virFileDeleteTree(filepath) < 0)
+                goto cleanup;
+        } else {
+            if (unlink(filepath) < 0 && errno != ENOENT) {
+                virReportSystemError(errno,
+                                     _("Cannot delete file '%s'"),
+                                     filepath);
+                goto cleanup;
+            }
+        }
+
+        VIR_FREE(filepath);
+        errno = 0;
+    }
+
+    if (errno) {
+        virReportSystemError(errno, _("Cannot read dir '%s'"),
+                             dir);
+        goto cleanup;
+    }
+
+    if (rmdir(dir) < 0 && errno != ENOENT) {
+        virReportSystemError(errno,
+                             _("Cannot delete directory '%s'"),
+                             dir);
+        goto cleanup;
+    }
+
+    ret = 0;
+
+cleanup:
+    VIR_FREE(filepath);
+    closedir(dh);
+    return ret;
+}
diff --git a/src/util/virfile.h b/src/util/virfile.h
index c885b73..5f0dd2b 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -108,4 +108,6 @@ int virFileUpdatePerm(const char *path,
 int virFileLoopDeviceAssociate(const char *file,
                                char **dev);
 
+int virFileDeleteTree(const char *dir);
+
 #endif /* __VIR_FILES_H */
-- 
1.8.1.4




More information about the libvir-list mailing list