chiark / gitweb /
rm-rf: never cross mount points
[elogind.git] / src / shared / rm-rf.c
index 99d12b11c6da6362c111ba7f2105ccd449045a9a..eeb2e3919659a3d9a7a051dd1b5af915579a66c5 100644 (file)
@@ -89,7 +89,7 @@ int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev) {
                 if (is_dir) {
                         int subdir_fd;
 
                 if (is_dir) {
                         int subdir_fd;
 
-                        /* if root_dev is set, remove subdirectories only, if device is same as dir */
+                        /* if root_dev is set, remove subdirectories only if device is same */
                         if (root_dev && st.st_dev != root_dev->st_dev)
                                 continue;
 
                         if (root_dev && st.st_dev != root_dev->st_dev)
                                 continue;
 
@@ -100,6 +100,20 @@ int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev) {
                                 continue;
                         }
 
                                 continue;
                         }
 
+                        /* Stop at mount points */
+                        r = fd_is_mount_point(subdir_fd);
+                        if (r < 0) {
+                                if (ret == 0 && r != -ENOENT)
+                                        ret = r;
+
+                                safe_close(subdir_fd);
+                                continue;
+                        }
+                        if (r) {
+                                safe_close(subdir_fd);
+                                continue;
+                        }
+
                         /* We pass REMOVE_PHYSICAL here, to avoid
                          * doing the fstatfs() to check the file
                          * system type again for each directory */
                         /* We pass REMOVE_PHYSICAL here, to avoid
                          * doing the fstatfs() to check the file
                          * system type again for each directory */
@@ -162,7 +176,6 @@ int rm_rf(const char *path, RemoveFlags flags) {
         r = rm_rf_children(fd, flags, NULL);
 
         if (flags & REMOVE_ROOT) {
         r = rm_rf_children(fd, flags, NULL);
 
         if (flags & REMOVE_ROOT) {
-
                 if (rmdir(path) < 0 && errno != ENOENT) {
                         if (r == 0)
                                 r = -errno;
                 if (rmdir(path) < 0 && errno != ENOENT) {
                         if (r == 0)
                                 r = -errno;