diff options
-rw-r--r-- | arch/um/os-Linux/umid.c | 53 |
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 | ||
70 | static 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 | */ | ||
76 | static 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; | ||
114 | out: | ||
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 | ||