summaryrefslogtreecommitdiffstats
path: root/sys-utils/switch_root.c
diff options
context:
space:
mode:
authorKarel Zak2014-03-04 11:45:44 +0100
committerKarel Zak2014-03-04 11:45:44 +0100
commit7ad19a3feb8fc9009b69b379c5c98220d2e34e76 (patch)
tree750fdd2b38e9e0907e3e8d451e3f6a4a17d5617e /sys-utils/switch_root.c
parentlib/sysfs: make dirent d_type usage more robust (diff)
downloadkernel-qcow2-util-linux-7ad19a3feb8fc9009b69b379c5c98220d2e34e76.tar.gz
kernel-qcow2-util-linux-7ad19a3feb8fc9009b69b379c5c98220d2e34e76.tar.xz
kernel-qcow2-util-linux-7ad19a3feb8fc9009b69b379c5c98220d2e34e76.zip
switch_root: make dirent d_type usage more robust
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'sys-utils/switch_root.c')
-rw-r--r--sys-utils/switch_root.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/sys-utils/switch_root.c b/sys-utils/switch_root.c
index f26f7dae4..1222fb1b4 100644
--- a/sys-utils/switch_root.c
+++ b/sys-utils/switch_root.c
@@ -68,6 +68,7 @@ static int recursiveRemove(int fd)
while(1) {
struct dirent *d;
+ int isdir = 0;
errno = 0;
if (!(d = readdir(dir))) {
@@ -80,8 +81,10 @@ static int recursiveRemove(int fd)
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
continue;
-
- if (d->d_type == DT_DIR) {
+#ifdef _DIRENT_HAVE_D_TYPE
+ if (d->d_type == DT_DIR || d->d_type == DT_UNKNOWN)
+#endif
+ {
struct stat sb;
if (fstatat(dfd, d->d_name, &sb, AT_SYMLINK_NOFOLLOW)) {
@@ -90,7 +93,7 @@ static int recursiveRemove(int fd)
}
/* remove subdirectories if device is same as dir */
- if (sb.st_dev == rb.st_dev) {
+ if (S_ISDIR(sb.st_mode) && sb.st_dev == rb.st_dev) {
int cfd;
cfd = openat(dfd, d->d_name, O_RDONLY);
@@ -98,12 +101,12 @@ static int recursiveRemove(int fd)
recursiveRemove(cfd);
close(cfd);
}
+ isdir = 1;
} else
continue;
}
- if (unlinkat(dfd, d->d_name,
- d->d_type == DT_DIR ? AT_REMOVEDIR : 0))
+ if (unlinkat(dfd, d->d_name, isdir ? AT_REMOVEDIR : 0))
warn(_("failed to unlink %s"), d->d_name);
}