static int fs_crypt_write_stream_finish(struct fs_file *_file, bool success) { struct crypt_fs_file *file = (struct crypt_fs_file *)_file; struct istream *input; int ret; if (_file->output != NULL) { if (_file->output == file->super_output) _file->output = NULL; else o_stream_unref(&_file->output); } if (!success) { if (file->super_output != NULL) { /* no encryption */ i_assert(file->temp_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)); } else if (file->temp_output != NULL) { o_stream_destroy(&file->temp_output); } return -1; } if (file->super_output != NULL) { /* no encrypt */ i_assert(file->temp_output == NULL); return fs_write_stream_finish(_file->parent, &file->super_output); } if (file->temp_output == NULL) { /* finishing up */ i_assert(file->super_output == NULL); return fs_write_stream_finish_async(_file->parent); } /* finish writing the temporary file */ input = iostream_temp_finish(&file->temp_output, IO_BLOCK_SIZE); file->super_output = fs_write_stream(_file->parent); o_stream_nsend_istream(file->super_output, input); ret = fs_write_stream_finish(_file->parent, &file->super_output); i_stream_unref(&input); return ret; }
static void test_fs_async_write(const char *test_name, struct fs *fs) { struct fs_file *file; struct test_fs_file *test_file; struct ostream *output; unsigned int i; test_begin(t_strdup_printf("%s: async write", test_name)); for (i = 0; i < 3; i++) { file = fs_file_init(fs, "foo", FS_OPEN_MODE_REPLACE | FS_OPEN_FLAG_ASYNC); output = fs_write_stream(file); o_stream_nsend_str(output, "12345"); if (i < 2) { test_assert(fs_write_stream_finish(file, &output) == 0); test_assert(output == NULL); test_assert(fs_write_stream_finish_async(file) == 0); } test_file = test_fs_file_get(fs, "foo"); test_file->wait_async = FALSE; switch (i) { case 0: test_assert(fs_write_stream_finish_async(file) > 0); test_assert(test_file->contents->used > 0); break; case 1: test_file->io_failure = TRUE; test_assert(fs_write_stream_finish_async(file) < 0); test_assert(test_file->contents->used == 0); break; case 2: fs_write_stream_abort_error(file, &output, "test"); test_assert(test_file->contents->used == 0); break; } fs_file_deinit(&file); } test_end(); }