shm-path: remove directory hierarchy on destroy
[lttng-tools.git] / src / common / utils.c
index 9a53330004931408df017fb4b2ebbd87ad31a61e..f9e6a99eafeec26afa4c7640f8a8d5a2c64178b1 100644 (file)
@@ -32,6 +32,7 @@
 #include <grp.h>
 #include <pwd.h>
 #include <sys/file.h>
+#include <dirent.h>
 
 #include <common/common.h>
 #include <common/runas.h>
@@ -1058,3 +1059,67 @@ char *utils_generate_optstring(const struct option *long_options,
 end:
        return optstring;
 }
+
+/*
+ * Try to remove a hierarchy of empty directories, recursively. Don't unlink
+ * any file.
+ */
+LTTNG_HIDDEN
+int utils_recursive_rmdir(const char *path)
+{
+       DIR *dir;
+       int dir_fd, ret = 0, closeret;
+       struct dirent *entry;
+
+       /* Open directory */
+       dir = opendir(path);
+       if (!dir) {
+               PERROR("Cannot open '%s' path", path);
+               return -1;
+       }
+       dir_fd = dirfd(dir);
+       if (dir_fd < 0) {
+               PERROR("dirfd");
+               return -1;
+       }
+
+       while ((entry = readdir(dir))) {
+               if (!strcmp(entry->d_name, ".")
+                               || !strcmp(entry->d_name, ".."))
+                       continue;
+               switch (entry->d_type) {
+               case DT_DIR:
+               {
+                       char subpath[PATH_MAX];
+
+                       strncpy(subpath, path, PATH_MAX);
+                       subpath[PATH_MAX - 1] = '\0';
+                       strncat(subpath, "/",
+                               PATH_MAX - strlen(subpath) - 1);
+                       strncat(subpath, entry->d_name,
+                               PATH_MAX - strlen(subpath) - 1);
+                       ret = utils_recursive_rmdir(subpath);
+                       if (ret) {
+                               goto end;
+                       }
+                       break;
+               }
+               case DT_REG:
+                       ret = -EBUSY;
+                       goto end;
+               default:
+                       ret = -EINVAL;
+                       goto end;
+               }
+       }
+end:
+       closeret = closedir(dir);
+       if (closeret) {
+               PERROR("closedir");
+       }
+       if (!ret) {
+               DBG3("Attempting rmdir %s", path);
+               ret = rmdir(path);
+       }
+       return ret;
+}
This page took 0.026701 seconds and 5 git commands to generate.