/* free old error after strdup in case args point to the old error */
if (file != NULL) {
+ char *old_error = file->last_error;
file = fs_file_get_error_file(file);
+ if (old_error != NULL && strcmp(old_error, new_error) == 0) {
+ /* identical error - ignore */
+ } else if (file->last_error_changed) {
+ /* multiple fs_set_error() calls used without
+ fs_file_last_error() in the middle. */
+ e_error(file->event, "%s (overwriting error)", old_error);
+ }
+ if (errno == EAGAIN || errno == ENOENT || errno == EEXIST ||
+ errno == ENOTEMPTY) {
+ /* These are (or can be) expected errors - don't log
+ them if they have a missing fs_file_last_error()
+ call */
+ file->last_error_changed = FALSE;
+ } else {
+ file->last_error_changed = TRUE;
+ }
+
i_free(file->last_error);
file->last_error = new_error;
} else {
{
struct fs_file *error_file = fs_file_get_error_file(file);
+ error_file->last_error_changed = FALSE;
if (error_file->last_error == NULL)
return "BUG: Unknown file error";
return error_file->last_error;
va_list args;
va_start(args, error_fmt);
fs_set_verror(file->event, error_fmt, args);
+ /* the error shouldn't be automatically logged if
+ fs_file_last_error() is no longer used */
+ fs_file_get_error_file(file)->last_error_changed = FALSE;
fs_write_stream_abort(file, output);
va_end(args);
}
void fs_file_set_error_async(struct fs_file *file)
{
- fs_set_error(file->event, "Asynchronous operation in progress");
errno = EAGAIN;
+ fs_set_error(file->event, "Asynchronous operation in progress");
}
static uint64_t