if (file->copy_input != NULL) {
i_stream_unref(&file->copy_input);
- fs_write_stream_abort(file, &file->copy_output);
+ fs_write_stream_abort_error(file, &file->copy_output, "fs_file_close(%s)",
+ o_stream_get_name(file->copy_output));
}
i_free_and_null(file->write_digest);
if (file->fs->v.file_close != NULL) T_BEGIN {
return fs_write_stream_finish_int(file, TRUE);
}
-void fs_write_stream_abort_error(struct fs_file *file, struct ostream **output, const char *error_fmt, ...)
+static void fs_write_stream_abort_int(struct fs_file *file, struct ostream **output)
{
int ret;
- va_list args;
- va_start(args, error_fmt);
i_assert(*output == file->output);
i_assert(file->output != NULL);
*output = NULL;
o_stream_ignore_last_errors(file->output);
/* make sure we don't have an old error lying around */
- fs_set_verror(file->fs, error_fmt, args);
ret = fs_write_stream_finish_int(file, FALSE);
i_assert(ret != 0);
+}
+void fs_write_stream_abort_error(struct fs_file *file, struct ostream **output, const char *error_fmt, ...)
+{
+ va_list args;
+ va_start(args, error_fmt);
+ fs_set_verror(file->fs, error_fmt, args);
+ fs_write_stream_abort_int(file, output);
va_end(args);
}
fs_write_stream_abort_error(file, output, "Write aborted");
}
+void fs_write_stream_abort_parent(struct fs_file *file, struct ostream **output)
+{
+ i_assert(file->parent != NULL);
+ i_assert(fs_filelast_error(file->parent) != NULL);
+ fs_write_stream_abort_int(file, output);
+}
+
void fs_write_set_hash(struct fs_file *file, const struct hash_method *method,
const void *digest)
{
void fs_write_stream_abort(struct fs_file *file, struct ostream **output);
void fs_write_stream_abort_error(struct fs_file *file, struct ostream **output, const char *error_fmt, ...) ATTR_FORMAT(3, 4);
+/* Same as above, except it closes the *parent* file and error is left untouched */
+void fs_write_stream_abort_parent(struct fs_file *file, struct ostream **output);
+
/* Set a hash to the following write. The storage can then verify that the
input data matches the specified hash, or fail if it doesn't. Typically
implemented by Content-MD5 header. */
if (file->super_output != NULL) {
/* no metawrap */
i_assert(file->temp_output == NULL);
- fs_write_stream_abort_error(_file->parent, &file->super_output, "error(%s): %s",
- o_stream_get_name(file->super_output),
- o_stream_get_error(file->super_output));
+ fs_write_stream_abort_parent(_file->parent, &file->super_output);
} else {
i_assert(file->temp_output != NULL);
o_stream_destroy(&file->temp_output);
if (!success) {
if (_file->parent != NULL)
- fs_write_stream_abort_error(_file->parent, &_file->output,
- "write(%s) failed: %s",
- o_stream_get_name(_file->output),
- o_stream_get_error(_file->output));
+ fs_write_stream_abort_parent(_file->parent, &_file->output);
return -1;
}
if (!success) {
if (_file->parent != NULL)
- fs_write_stream_abort_error(_file->parent, &file->fs_output,
- "write(%s) error: %s",
- o_stream_get_name(file->fs_output),
- o_stream_get_error(file->fs_output));
+ fs_write_stream_abort_parent(_file->parent, &file->fs_output);
o_stream_unref(&_file->output);
return -1;
}
i_stream_is_eof(file->hash_input)) {
o_stream_unref(&_file->output);
if (fs_sis_try_link(file)) {
- fs_write_stream_abort(_file->parent, &file->fs_output);
+ fs_write_stream_abort_parent(_file->parent, &file->fs_output);
return 1;
}
}
int fs_wrapper_write_stream_finish(struct fs_file *file, bool success)
{
if (!success) {
- fs_write_stream_abort_error(file->parent, &file->output,
- "write(%s) failed: %s",
- o_stream_get_name(file->output),
- o_stream_get_error(file->output));
+ fs_write_stream_abort_parent(file->parent, &file->output);
return -1;
}
if (file->temp_output != NULL)
o_stream_destroy(&file->temp_output);
if (file->super_output != NULL)
- fs_write_stream_abort_error(_file->parent, &file->super_output,
- "write(%s) failed: %s",
- o_stream_get_name(file->super_output),
- o_stream_get_error(file->super_output));
+ fs_write_stream_abort_parent(_file->parent, &file->super_output);
return -1;
}