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 | ||
