commit 32efa14595f1d2b71bdbac06143bbd13c2fe9fc0
parent 941ffd2aed35c05346c1c77ab3cbfcc75b8e494a
Author: sin <sin@2f30.org>
Date: Fri, 27 Jun 2014 11:57:26 +0100
Fix switch_root delete_content()
Diffstat:
M | switch_root.c | | | 57 | +++++++++++++++++++++++++++++---------------------------- |
1 file changed, 29 insertions(+), 28 deletions(-)
diff --git a/switch_root.c b/switch_root.c
@@ -17,42 +17,43 @@
static void
delete_content(const char *dir, dev_t curdevice)
{
- static char path[PATH_MAX];
+ char path[PATH_MAX];
DIR *d;
struct stat st;
struct dirent *dent;
/* don't dive into other filesystems */
- if (lstat(dir, &st) || st.st_dev != curdevice)
+ if (lstat(dir, &st) < 0 || st.st_dev != curdevice)
return;
- /* delete contents recursively */
- if (S_ISDIR(st.st_mode)) {
- d = opendir(dir);
- if (d) {
- for(; (dent = readdir(d)) ;) {
- /* skip ".." and "." */
- if (strcmp(dent->d_name, ".") == 0 ||
- strcmp(dent->d_name, "..") == 0)
- continue;
-
- /* build path and dive deeper */
- if (strlcat(path, dir, sizeof(path)) >= sizeof(path))
- eprintf("path too long\n");
- if (strlcat(path, dent->d_name, sizeof(path)) >= sizeof(path))
- eprintf("path too long\n");
-
- delete_content(path, curdevice);
- path[0] = 0;
- }
- closedir(d);
-
- /* remove now empty dir */
- rmdir(dir);
+ if (!(d = opendir(dir)))
+ return;
+ while ((dent = readdir(d))) {
+ if (strcmp(dent->d_name, ".") == 0 ||
+ strcmp(dent->d_name, "..") == 0)
+ continue;
+
+ /* build path and dive deeper */
+ if (strlcpy(path, dir, sizeof(path)) >= sizeof(path))
+ eprintf("path too long\n");
+ if (path[strlen(path) - 1] != '/')
+ if (strlcat(path, "/", sizeof(path)) >= sizeof(path))
+ eprintf("path too long\n");
+ if (strlcat(path, dent->d_name, sizeof(path)) >= sizeof(path))
+ eprintf("path too long\n");
+
+ if (lstat(path, &st) < 0)
+ weprintf("lstat %s:", path);
+
+ if (S_ISDIR(st.st_mode)) {
+ delete_content(path, curdevice);
+ if (rmdir(path) < 0)
+ weprintf("rmdir %s:", path);
+ } else {
+ if (unlink(path) < 0)
+ weprintf("unlink %s:", path);
}
- } else {
- /* unlink non-directory */
- unlink(dir);
}
+ closedir(d);
}
static void