# HG changeset patch # User Timo Sirainen # Date 1498567152 -10800 # Node ID 471c8c88c5d12895ea5f02fc7d350f8e0ac9643f # Parent 7adf8266c54ba079b5b31e89690d4a652ad79fc9 lib-storage: mailbox_list_delete_mailbox_nonrecursive() - Fix error handling It should return error on unexpected readdir(), closedir() and unlink() failures. Also fix handling a race condition with another process deleting the mailbox at the same time. diff -r 7adf8266c54b -r 471c8c88c5d1 src/lib-storage/list/mailbox-list-delete.c --- a/src/lib-storage/list/mailbox-list-delete.c Tue Jun 27 16:56:08 2017 +0300 +++ b/src/lib-storage/list/mailbox-list-delete.c Tue Jun 27 15:39:12 2017 +0300 @@ -146,6 +146,7 @@ string_t *full_path; size_t dir_len; bool mailbox_dir, unlinked_something = FALSE; + int ret = 0; if (mailbox_list_check_root_delete(list, name, path) < 0) return -1; @@ -203,20 +204,30 @@ else if (errno != ENOENT && !UNLINK_EISDIR(errno)) { mailbox_list_set_critical(list, "unlink(%s) failed: %m", str_c(full_path)); + ret = -1; } } - if (errno != 0) + if (errno != 0) { mailbox_list_set_critical(list, "readdir(%s) failed: %m", path); + ret = -1; + } if (closedir(dir) < 0) { mailbox_list_set_critical(list, "closedir(%s) failed: %m", path); + ret = -1; } + if (ret < 0) + return -1; if (rmdir_path) { if (rmdir(path) == 0) unlinked_something = TRUE; - else if (errno != ENOENT && - errno != ENOTEMPTY && errno != EEXIST) { + else if (errno == ENOENT) { + /* race condition with another process, which finished + deleting it first. */ + mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, + T_MAILBOX_LIST_ERR_NOT_FOUND(list, name)); + } else if (errno != ENOTEMPTY && errno != EEXIST) { mailbox_list_set_critical(list, "rmdir(%s) failed: %m", path); return -1;