From 10a2e8716e9040908fb60fcda56b5315ea4c1312 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Mon, 12 Jul 2010 15:14:45 +0100 Subject: [PATCH] Handle rmdir() failing with EEXIST the same as failing with ENOTEMPTY. This is allowed by POSIX, and at least Solaris does that. --- src/lib-storage/list/mailbox-list-delete.c | 5 +++-- src/lib-storage/list/mailbox-list-fs.c | 12 +++++++----- src/lib/unlink-directory.c | 14 ++++++++++++-- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/lib-storage/list/mailbox-list-delete.c b/src/lib-storage/list/mailbox-list-delete.c index 3598dadc89..9671af4f78 100644 --- a/src/lib-storage/list/mailbox-list-delete.c +++ b/src/lib-storage/list/mailbox-list-delete.c @@ -219,7 +219,8 @@ int mailbox_list_delete_mailbox_nonrecursive(struct mailbox_list *list, if (rmdir_path) { if (rmdir(path) == 0) unlinked_something = TRUE; - else if (errno != ENOENT && errno != ENOTEMPTY) { + else if (errno != ENOENT && + errno != ENOTEMPTY && errno != EEXIST) { mailbox_list_set_critical(list, "rmdir(%s) failed: %m", path); return -1; @@ -260,7 +261,7 @@ void mailbox_list_delete_until_root(struct mailbox_list *list, const char *path, } while (strcmp(path, root_dir) != 0) { if (rmdir(path) < 0 && errno != ENOENT) { - if (errno == ENOTEMPTY) + if (errno == ENOTEMPTY || errno == EEXIST) return; mailbox_list_set_critical(list, "rmdir(%s) failed: %m", diff --git a/src/lib-storage/list/mailbox-list-fs.c b/src/lib-storage/list/mailbox-list-fs.c index 2261e53dfc..0df5fd238b 100644 --- a/src/lib-storage/list/mailbox-list-fs.c +++ b/src/lib-storage/list/mailbox-list-fs.c @@ -391,7 +391,8 @@ static int fs_list_delete_mailbox(struct mailbox_list *list, const char *name) /* try to delete the parent directory */ path = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_DIR); - if (rmdir(path) < 0 && errno != ENOENT && errno != ENOTEMPTY) { + if (rmdir(path) < 0 && errno != ENOENT && + errno != ENOTEMPTY && errno != EEXIST) { mailbox_list_set_critical(list, "rmdir(%s) failed: %m", path); } @@ -435,7 +436,7 @@ static int fs_list_delete_dir(struct mailbox_list *list, const char *name) if (errno == ENOENT) { mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, T_MAIL_ERR_MAILBOX_NOT_FOUND(name)); - } else if (errno == ENOTEMPTY) { + } else if (errno == ENOTEMPTY || errno == EEXIST) { /* mbox workaround: if only .imap/ directory is preventing the deletion, remove it */ child_name = t_strdup_printf("%s%cchild", name, @@ -479,8 +480,8 @@ static int rename_dir(struct mailbox_list *oldlist, const char *oldname, } if (rmdir_parent && (p = strrchr(oldpath, '/')) != NULL) { oldpath = t_strdup_until(oldpath, p); - if (rmdir(oldpath) < 0 && - errno != ENOENT && errno != ENOTEMPTY) { + if (rmdir(oldpath) < 0 && errno != ENOENT && + errno != ENOTEMPTY && errno != EEXIST) { mailbox_list_set_critical(oldlist, "rmdir(%s) failed: %m", oldpath); } @@ -603,7 +604,8 @@ static int fs_list_rename_mailbox(struct mailbox_list *oldlist, MAILBOX_LIST_PATH_TYPE_DIR); if (rmdir(oldpath) == 0) rmdir_parent = TRUE; - else if (errno != ENOENT && errno != ENOTEMPTY) { + else if (errno != ENOENT && + errno != ENOTEMPTY && errno != EEXIST) { mailbox_list_set_critical(oldlist, "rmdir(%s) failed: %m", oldpath); } diff --git a/src/lib/unlink-directory.c b/src/lib/unlink-directory.c index dc4b3cf776..5dc3c74acf 100644 --- a/src/lib/unlink-directory.c +++ b/src/lib/unlink-directory.c @@ -117,8 +117,13 @@ static int unlink_directory_r(const char *dir) break; if (rmdir(d->d_name) < 0) { - if (errno != ENOENT) + if (errno != ENOENT) { + if (errno == EEXIST) { + /* standardize errno */ + errno = ENOTEMPTY; + } break; + } errno = 0; } } else { @@ -169,8 +174,13 @@ int unlink_directory(const char *dir, bool unlink_dir) } if (unlink_dir) { - if (rmdir(dir) < 0 && errno != ENOENT) + if (rmdir(dir) < 0 && errno != ENOENT) { + if (errno == EEXIST) { + /* standardize errno */ + errno = ENOTEMPTY; + } return -1; + } } return 0; -- 2.47.3