aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/um/os-Linux/umid.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
index d5811710126e..48092b95c8ab 100644
--- a/arch/um/os-Linux/umid.c
+++ b/arch/um/os-Linux/umid.c
@@ -67,32 +67,53 @@ err:
67 return err; 67 return err;
68} 68}
69 69
70static int actually_do_remove(char *dir) 70/*
71 * Unlinks the files contained in @dir and then removes @dir.
72 * Doesn't handle directory trees, so it's not like rm -rf, but almost such. We
73 * ignore ENOENT errors for anything (they happen, strangely enough - possibly due
74 * to races between multiple dying UML threads).
75 */
76static int remove_files_and_dir(char *dir)
71{ 77{
72 DIR *directory; 78 DIR *directory;
73 struct dirent *ent; 79 struct dirent *ent;
74 int len; 80 int len;
75 char file[256]; 81 char file[256];
82 int ret;
76 83
77 directory = opendir(dir); 84 directory = opendir(dir);
78 if(directory == NULL) 85 if (directory == NULL) {
79 return -errno; 86 if (errno != ENOENT)
87 return -errno;
88 else
89 return 0;
90 }
80 91
81 while((ent = readdir(directory)) != NULL){ 92 while ((ent = readdir(directory)) != NULL) {
82 if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) 93 if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
83 continue; 94 continue;
84 len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1; 95 len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1;
85 if(len > sizeof(file)) 96 if (len > sizeof(file)) {
86 return -E2BIG; 97 ret = -E2BIG;
98 goto out;
99 }
87 100
88 sprintf(file, "%s/%s", dir, ent->d_name); 101 sprintf(file, "%s/%s", dir, ent->d_name);
89 if(unlink(file) < 0) 102 if (unlink(file) < 0 && errno != ENOENT) {
90 return -errno; 103 ret = -errno;
104 goto out;
105 }
91 } 106 }
92 if(rmdir(dir) < 0)
93 return -errno;
94 107
95 return 0; 108 if (rmdir(dir) < 0 && errno != ENOENT) {
109 ret = -errno;
110 goto out;
111 }
112
113 ret = 0;
114out:
115 closedir(directory);
116 return ret;
96} 117}
97 118
98/* This says that there isn't already a user of the specified directory even if 119/* This says that there isn't already a user of the specified directory even if
@@ -172,9 +193,9 @@ static int umdir_take_if_dead(char *dir)
172 if (is_umdir_used(dir)) 193 if (is_umdir_used(dir))
173 return -EEXIST; 194 return -EEXIST;
174 195
175 ret = actually_do_remove(dir); 196 ret = remove_files_and_dir(dir);
176 if (ret) { 197 if (ret) {
177 printk("is_umdir_used - actually_do_remove failed with " 198 printk("is_umdir_used - remove_files_and_dir failed with "
178 "err = %d\n", ret); 199 "err = %d\n", ret);
179 } 200 }
180 return ret; 201 return ret;
@@ -354,9 +375,9 @@ static void remove_umid_dir(void)
354 char dir[strlen(uml_dir) + UMID_LEN + 1], err; 375 char dir[strlen(uml_dir) + UMID_LEN + 1], err;
355 376
356 sprintf(dir, "%s%s", uml_dir, umid); 377 sprintf(dir, "%s%s", uml_dir, umid);
357 err = actually_do_remove(dir); 378 err = remove_files_and_dir(dir);
358 if(err) 379 if(err)
359 printf("remove_umid_dir - actually_do_remove failed with " 380 printf("remove_umid_dir - remove_files_and_dir failed with "
360 "err = %d\n", err); 381 "err = %d\n", err);
361} 382}
362 383