diff options
author | Karel Zak | 2014-03-04 11:45:44 +0100 |
---|---|---|
committer | Karel Zak | 2014-03-04 11:45:44 +0100 |
commit | 7ad19a3feb8fc9009b69b379c5c98220d2e34e76 (patch) | |
tree | 750fdd2b38e9e0907e3e8d451e3f6a4a17d5617e /sys-utils | |
parent | lib/sysfs: make dirent d_type usage more robust (diff) | |
download | kernel-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')
-rw-r--r-- | sys-utils/switch_root.c | 13 |
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); } |