From 7ad19a3feb8fc9009b69b379c5c98220d2e34e76 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 4 Mar 2014 11:45:44 +0100 Subject: switch_root: make dirent d_type usage more robust Signed-off-by: Karel Zak --- sys-utils/switch_root.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'sys-utils/switch_root.c') 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); } -- cgit v1.2.3-55-g7522