# HG changeset patch # User Timo Sirainen # Date 1340571719 -10800 # Node ID ca37d157729170c87db6ba2075c51d15be9d6f3e # Parent 3ffdb4bf36d348b6ddd694794a924525670da6f7 Added o_stream_nsend*() and related functions to make delayed error handling safer. Once o_stream_nsend*() is called, o_stream_nfinish() must be called before stream is destroyed to finish checking if there were any errors. If something failed and the stream is just wanted to be closed, o_stream_ignore_last_errors() can be called. For streams where errors don't really make any difference (network sockets) you can call o_stream_set_no_error_handling() immediately after creating the stream. diff -r 3ffdb4bf36d3 -r ca37d1577291 src/anvil/anvil-connection.c --- a/src/anvil/anvil-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/anvil/anvil-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -90,15 +90,15 @@ return -1; } value = connect_limit_lookup(connect_limit, args[0]); - (void)o_stream_send_str(conn->output, - t_strdup_printf("%u\n", value)); + o_stream_nsend_str(conn->output, + t_strdup_printf("%u\n", value)); } else if (strcmp(cmd, "PENALTY-GET") == 0) { if (args[0] == NULL) { *error_r = "PENALTY-GET: Not enough parameters"; return -1; } value = penalty_get(penalty, args[0], &stamp); - (void)o_stream_send_str(conn->output, + o_stream_nsend_str(conn->output, t_strdup_printf("%u %s\n", value, dec2str(stamp))); } else if (strcmp(cmd, "PENALTY-INC") == 0) { if (args[0] == NULL || args[1] == NULL || args[2] == NULL) { @@ -183,8 +183,10 @@ conn = i_new(struct anvil_connection, 1); conn->fd = fd; conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); - if (!fifo) + if (!fifo) { conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); + } conn->io = io_add(fd, IO_READ, anvil_connection_input, conn); conn->master = master; conn->fifo = fifo; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/anvil/connect-limit.c --- a/src/anvil/connect-limit.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/anvil/connect-limit.c Mon Jun 25 00:01:59 2012 +0300 @@ -185,5 +185,5 @@ break; } hash_table_iterate_deinit(&iter); - (void)o_stream_send(output, "\n", 1); + o_stream_nsend(output, "\n", 1); } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/anvil/penalty.c --- a/src/anvil/penalty.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/anvil/penalty.c Mon Jun 25 00:01:59 2012 +0300 @@ -268,5 +268,5 @@ if (o_stream_send(output, str_data(str), str_len(str)) < 0) break; } - (void)o_stream_send(output, "\n", 1); + o_stream_nsend(output, "\n", 1); } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/auth/auth-client-connection.c --- a/src/auth/auth-client-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/auth/auth-client-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -54,7 +54,7 @@ iov[0].iov_len = strlen(cmd); iov[1].iov_base = "\n"; iov[1].iov_len = 1; - (void)o_stream_sendv(conn->output, iov, 2); + o_stream_nsendv(conn->output, iov, 2); if (o_stream_get_buffer_used_size(conn->output) >= OUTBUF_THROTTLE_SIZE) { @@ -292,8 +292,8 @@ auth_client_connection_unref(&conn); } -struct auth_client_connection * -auth_client_connection_create(struct auth *auth, int fd, bool login_requests) +void auth_client_connection_create(struct auth *auth, int fd, + bool login_requests) { static unsigned int connect_uid_counter = 0; struct auth_client_connection *conn; @@ -310,6 +310,7 @@ conn->input = i_stream_create_fd(fd, AUTH_CLIENT_MAX_LINE_LENGTH, FALSE); conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); o_stream_set_flush_callback(conn->output, auth_client_output, conn); conn->io = io_add(fd, IO_READ, auth_client_input, conn); @@ -325,8 +326,6 @@ if (o_stream_send(conn->output, str_data(str), str_len(str)) < 0) auth_client_disconnected(&conn); - - return conn; } void auth_client_connection_destroy(struct auth_client_connection **_conn) diff -r 3ffdb4bf36d3 -r ca37d1577291 src/auth/auth-client-connection.h --- a/src/auth/auth-client-connection.h Sun Jun 24 21:43:48 2012 +0300 +++ b/src/auth/auth-client-connection.h Mon Jun 25 00:01:59 2012 +0300 @@ -22,8 +22,8 @@ unsigned int version_received:1; }; -struct auth_client_connection * -auth_client_connection_create(struct auth *auth, int fd, bool login_requests); +void auth_client_connection_create(struct auth *auth, int fd, + bool login_requests); void auth_client_connection_destroy(struct auth_client_connection **conn); struct auth_client_connection * diff -r 3ffdb4bf36d3 -r ca37d1577291 src/auth/auth-master-connection.c --- a/src/auth/auth-master-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/auth/auth-master-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -87,7 +87,7 @@ iov[1].iov_base = "\n"; iov[1].iov_len = 1; - (void)o_stream_sendv(conn->output, iov, 2); + o_stream_nsendv(conn->output, iov, 2); } static bool @@ -119,19 +119,19 @@ if (client_conn == NULL) { i_error("Master requested auth for nonexistent client %u", client_pid); - (void)o_stream_send_str(conn->output, - t_strdup_printf("FAIL\t%u\n", id)); + o_stream_nsend_str(conn->output, + t_strdup_printf("FAIL\t%u\n", id)); } else if (memcmp(client_conn->cookie, cookie, sizeof(cookie)) != 0) { i_error("Master requested auth for client %u with invalid cookie", client_pid); - (void)o_stream_send_str(conn->output, - t_strdup_printf("FAIL\t%u\n", id)); + o_stream_nsend_str(conn->output, + t_strdup_printf("FAIL\t%u\n", id)); } else if (!auth_request_handler_master_request( client_conn->request_handler, conn, id, client_id)) { i_error("Master requested auth for non-login client %u", client_pid); - (void)o_stream_send_str(conn->output, - t_strdup_printf("FAIL\t%u\n", id)); + o_stream_nsend_str(conn->output, + t_strdup_printf("FAIL\t%u\n", id)); } return TRUE; } @@ -260,7 +260,7 @@ } str_append_c(str, '\n'); - (void)o_stream_send(conn->output, str_data(str), str_len(str)); + o_stream_nsend(conn->output, str_data(str), str_len(str)); auth_request_unref(&auth_request); auth_master_connection_unref(&conn); @@ -320,7 +320,7 @@ i_debug("master out: %s", str_c(str)); str_append_c(str, '\n'); - (void)o_stream_send(conn->output, str_data(str), str_len(str)); + o_stream_nsend(conn->output, str_data(str), str_len(str)); auth_request_unref(&auth_request); auth_master_connection_unref(&conn); @@ -446,7 +446,7 @@ str = t_strdup_printf("DONE\t%u\t%s\n", ctx->auth_request->id, ctx->failed ? "fail" : ""); - (void)o_stream_send_str(ctx->conn->output, str); + o_stream_nsend_str(ctx->conn->output, str); master_input_list_finish(ctx); return; } @@ -496,7 +496,7 @@ i_error("Auth client doesn't have permissions to list users: %s", auth_restricted_reason(conn)); str = t_strdup_printf("DONE\t%u\tfail\n", id); - (void)o_stream_send_str(conn->output, str); + o_stream_nsend_str(conn->output, str); return TRUE; } @@ -505,7 +505,7 @@ if (userdb == NULL) { i_error("Trying to iterate users, but userdbs don't support it"); str = t_strdup_printf("DONE\t%u\tfail\n", id); - (void)o_stream_send_str(conn->output, str); + o_stream_nsend_str(conn->output, str); return TRUE; } @@ -693,6 +693,7 @@ conn->auth = auth; conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); o_stream_set_flush_callback(conn->output, master_output, conn); conn->io = io_add(fd, IO_READ, master_input, conn); conn->userdb_only = userdb_only; @@ -701,7 +702,7 @@ AUTH_MASTER_PROTOCOL_MAJOR_VERSION, AUTH_MASTER_PROTOCOL_MINOR_VERSION, my_pid); - (void)o_stream_send_str(conn->output, line); + o_stream_nsend_str(conn->output, line); DLLIST_PREPEND(&auth_master_connections, conn); if (auth_master_connection_set_permissions(conn, socket_st) < 0) { diff -r 3ffdb4bf36d3 -r ca37d1577291 src/auth/auth-postfix-connection.c --- a/src/auth/auth-postfix-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/auth/auth-postfix-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -95,7 +95,7 @@ i_debug("postfix out: %s", str_c(str)); str_append_c(str, '\n'); - (void)o_stream_send(conn->output, str_data(str), str_len(str)); + o_stream_nsend(conn->output, str_data(str), str_len(str)); i_assert(conn->io == NULL); if (!conn->destroyed) @@ -179,6 +179,7 @@ conn->auth = auth; conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); conn->io = io_add(fd, IO_READ, postfix_input, conn); DLLIST_PREPEND(&auth_postfix_connections, conn); return conn; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/auth/auth-worker-client.c --- a/src/auth/auth-worker-client.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/auth/auth-worker-client.c Mon Jun 25 00:01:59 2012 +0300 @@ -102,8 +102,8 @@ string_t *str) { if (worker_restart_request) - o_stream_send_str(client->output, "RESTART\n"); - o_stream_send(client->output, str_data(str), str_len(str)); + o_stream_nsend_str(client->output, "RESTART\n"); + o_stream_nsend(client->output, str_data(str), str_len(str)); } static void verify_plain_callback(enum passdb_result result, @@ -464,7 +464,7 @@ T_BEGIN { str = t_str_new(128); str_printfa(str, "%u\t*\t%s\n", ctx->auth_request->id, user); - o_stream_send(ctx->client->output, str_data(str), str_len(str)); + o_stream_nsend(ctx->client->output, str_data(str), str_len(str)); } T_END; if (ctx->sending) { @@ -694,6 +694,7 @@ client->input = i_stream_create_fd(fd, AUTH_WORKER_MAX_LINE_LENGTH, FALSE); client->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); o_stream_set_flush_callback(client->output, auth_worker_output, client); client->io = io_add(fd, IO_READ, auth_worker_input, client); auth_worker_refresh_proctitle(CLIENT_STATE_HANDSHAKE); @@ -755,7 +756,7 @@ auth_worker_client_error = TRUE; if (auth_worker_client != NULL && !auth_worker_client->error_sent) { - o_stream_send_str(auth_worker_client->output, "ERROR\n"); + o_stream_nsend_str(auth_worker_client->output, "ERROR\n"); auth_worker_client->error_sent = TRUE; } auth_worker_refresh_proctitle(""); @@ -766,7 +767,7 @@ auth_worker_client_error = FALSE; if (auth_worker_client != NULL && auth_worker_client->error_sent) { - o_stream_send_str(auth_worker_client->output, "SUCCESS\n"); + o_stream_nsend_str(auth_worker_client->output, "SUCCESS\n"); auth_worker_client->error_sent = FALSE; } auth_worker_refresh_proctitle(CLIENT_STATE_IDLE); @@ -775,6 +776,6 @@ void auth_worker_client_send_shutdown(void) { if (auth_worker_client != NULL) - o_stream_send_str(auth_worker_client->output, "SHUTDOWN\n"); + o_stream_nsend_str(auth_worker_client->output, "SHUTDOWN\n"); auth_worker_refresh_proctitle(CLIENT_STATE_STOP); } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/auth/auth-worker-server.c --- a/src/auth/auth-worker-server.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/auth/auth-worker-server.c Mon Jun 25 00:01:59 2012 +0300 @@ -101,7 +101,7 @@ iov[2].iov_base = "\n"; iov[2].iov_len = 1; - o_stream_sendv(conn->output, iov, 3); + o_stream_nsendv(conn->output, iov, 3); i_assert(conn->request == NULL); conn->request = request; @@ -145,7 +145,7 @@ binary_to_hex_append(str, userdb_md5, sizeof(userdb_md5)); str_append_c(str, '\n'); - o_stream_send(conn->output, str_data(str), str_len(str)); + o_stream_nsend(conn->output, str_data(str), str_len(str)); } static struct auth_worker_connection *auth_worker_create(void) @@ -173,6 +173,7 @@ conn->input = i_stream_create_fd(fd, AUTH_WORKER_MAX_LINE_LENGTH, FALSE); conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); conn->io = io_add(fd, IO_READ, worker_input, conn); conn->to = timeout_add(AUTH_WORKER_MAX_IDLE_SECS * 1000, auth_worker_idle_timeout, conn); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/auth/main.c --- a/src/auth/main.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/auth/main.c Mon Jun 25 00:01:59 2012 +0300 @@ -326,10 +326,10 @@ (void)auth_postfix_connection_create(auth, conn->fd); break; case AUTH_SOCKET_LOGIN_CLIENT: - (void)auth_client_connection_create(auth, conn->fd, TRUE); + auth_client_connection_create(auth, conn->fd, TRUE); break; case AUTH_SOCKET_CLIENT: - (void)auth_client_connection_create(auth, conn->fd, FALSE); + auth_client_connection_create(auth, conn->fd, FALSE); break; default: i_unreached(); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/auth/mech-winbind.c --- a/src/auth/mech-winbind.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/auth/mech-winbind.c Mon Jun 25 00:01:59 2012 +0300 @@ -177,7 +177,8 @@ base64_encode(data, data_size, str); str_append_c(str, '\n'); - if (o_stream_send_str(request->winbind->out_pipe, str_c(str)) < 0 || + if (o_stream_send(request->winbind->out_pipe, + str_data(str), str_len(str)) < 0 || o_stream_flush(request->winbind->out_pipe) < 0) { auth_request_log_error(auth_request, "winbind", "write(out_pipe) failed: %m"); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/config/config-connection.c --- a/src/config/config-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/config/config-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -52,15 +52,15 @@ struct ostream *output = context; const char *p; - o_stream_send_str(output, key); - o_stream_send_str(output, "="); + o_stream_nsend_str(output, key); + o_stream_nsend_str(output, "="); while ((p = strchr(value, '\n')) != NULL) { - o_stream_send(output, value, p-value); - o_stream_send(output, SETTING_STREAM_LF_CHAR, 1); + o_stream_nsend(output, value, p-value); + o_stream_nsend(output, SETTING_STREAM_LF_CHAR, 1); value = p+1; } - o_stream_send_str(output, value); - o_stream_send_str(output, "\n"); + o_stream_nsend_str(output, value); + o_stream_nsend_str(output, "\n"); } static int config_connection_request(struct config_connection *conn, @@ -99,7 +99,7 @@ /* master reads configuration only when reloading settings */ path = master_service_get_config_path(master_service); if (config_parse_file(path, TRUE, "", &error) <= 0) { - o_stream_send_str(conn->output, + o_stream_nsend_str(conn->output, t_strconcat("ERROR ", error, "\n", NULL)); config_connection_destroy(conn); return -1; @@ -117,25 +117,25 @@ const char *const *s; for (s = output.specific_services; *s != NULL; s++) { - o_stream_send_str(conn->output, + o_stream_nsend_str(conn->output, t_strdup_printf("service=%s\t", *s)); } } if (output.service_uses_local) - o_stream_send_str(conn->output, "service-uses-local\t"); + o_stream_nsend_str(conn->output, "service-uses-local\t"); if (output.service_uses_remote) - o_stream_send_str(conn->output, "service-uses-remote\t"); + o_stream_nsend_str(conn->output, "service-uses-remote\t"); if (output.used_local) - o_stream_send_str(conn->output, "used-local\t"); + o_stream_nsend_str(conn->output, "used-local\t"); if (output.used_remote) - o_stream_send_str(conn->output, "used-remote\t"); - o_stream_send_str(conn->output, "\n"); + o_stream_nsend_str(conn->output, "used-remote\t"); + o_stream_nsend_str(conn->output, "\n"); if (config_export_finish(&ctx) < 0) { config_connection_destroy(conn); return -1; } - o_stream_send_str(conn->output, "\n"); + o_stream_nsend_str(conn->output, "\n"); o_stream_uncork(conn->output); return 0; } @@ -188,6 +188,7 @@ conn->fd = fd; conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); conn->io = io_add(fd, IO_READ, config_connection_input, conn); DLLIST_PREPEND(&config_connections, conn); return conn; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/config/doveconf.c --- a/src/config/doveconf.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/config/doveconf.c Mon Jun 25 00:01:59 2012 +0300 @@ -242,8 +242,8 @@ if (prefix.str_pos != -1U) str_truncate(ctx->list_prefix, prefix.str_pos); else { - o_stream_send(output, indent_str, indent*2); - o_stream_send_str(output, "}\n"); + o_stream_nsend(output, indent_str, indent*2); + o_stream_nsend_str(output, "}\n"); } prefix_idx = prefix.prefix_idx; } else { @@ -285,7 +285,7 @@ goto again; } } - o_stream_send(output, str_data(ctx->list_prefix), str_len(ctx->list_prefix)); + o_stream_nsend(output, str_data(ctx->list_prefix), str_len(ctx->list_prefix)); str_truncate(ctx->list_prefix, 0); prefix_stack_reset_str(&prefix_stack); ctx->list_prefix_sent = TRUE; @@ -293,20 +293,20 @@ skip_len = prefix_idx == -1U ? 0 : strlen(prefixes[prefix_idx]); i_assert(skip_len == 0 || strncmp(prefixes[prefix_idx], strings[i], skip_len) == 0); - o_stream_send(output, indent_str, indent*2); + o_stream_nsend(output, indent_str, indent*2); key = strings[i] + skip_len; if (unique_key) key++; value = strchr(key, '='); - o_stream_send(output, key, value-key); - o_stream_send_str(output, " = "); + o_stream_nsend(output, key, value-key); + o_stream_nsend_str(output, " = "); if (!value_need_quote(value+1)) - o_stream_send_str(output, value+1); + o_stream_nsend_str(output, value+1); else { - o_stream_send(output, "\"", 1); - o_stream_send_str(output, str_escape(value+1)); - o_stream_send(output, "\"", 1); + o_stream_nsend(output, "\"", 1); + o_stream_nsend_str(output, str_escape(value+1)); + o_stream_nsend(output, "\"", 1); } - o_stream_send(output, "\n", 1); + o_stream_nsend(output, "\n", 1); end: ; } T_END; @@ -316,8 +316,8 @@ break; prefix_idx = prefix.prefix_idx; indent--; - o_stream_send(output, indent_str, indent*2); - o_stream_send_str(output, "}\n"); + o_stream_nsend(output, indent_str, indent*2); + o_stream_nsend_str(output, "}\n"); } /* flush output before writing errors */ @@ -382,8 +382,8 @@ { while (indent > 0) { indent--; - o_stream_send(output, indent_str, indent*2); - o_stream_send(output, "}\n", 2); + o_stream_nsend(output, indent_str, indent*2); + o_stream_nsend(output, "}\n", 2); } } @@ -427,6 +427,7 @@ int ret; output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE); + o_stream_set_no_error_handling(output, TRUE); o_stream_cork(output); ctx = config_dump_human_init(module, scope, TRUE); @@ -438,7 +439,7 @@ ret = config_dump_human_sections(output, filter, module); o_stream_uncork(output); - o_stream_unref(&output); + o_stream_destroy(&output); return ret; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/dict/dict-commands.c --- a/src/dict/dict-commands.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/dict/dict-commands.c Mon Jun 25 00:01:59 2012 +0300 @@ -34,12 +34,12 @@ if (ret > 0) { reply = t_strdup_printf("%c%s\n", DICT_PROTOCOL_REPLY_OK, value); - o_stream_send_str(conn->output, reply); + o_stream_nsend_str(conn->output, reply); } else { reply = t_strdup_printf("%c\n", ret == 0 ? DICT_PROTOCOL_REPLY_NOTFOUND : DICT_PROTOCOL_REPLY_FAIL); - o_stream_send_str(conn->output, reply); + o_stream_nsend_str(conn->output, reply); } return 0; } @@ -55,7 +55,7 @@ str_truncate(str, 0); str_printfa(str, "%c%s\t%s\n", DICT_PROTOCOL_REPLY_OK, key, value); - o_stream_send(conn->output, str_data(str), str_len(str)); + o_stream_nsend(conn->output, str_data(str), str_len(str)); if (o_stream_get_buffer_used_size(conn->output) > DICT_OUTPUT_OPTIMAL_SIZE) { @@ -75,7 +75,7 @@ if (dict_iterate_deinit(&conn->iter_ctx) < 0) str_append_c(str, DICT_PROTOCOL_REPLY_FAIL); str_append_c(str, '\n'); - o_stream_send(conn->output, str_data(str), str_len(str)); + o_stream_nsend(conn->output, str_data(str), str_len(str)); o_stream_uncork(conn->output); return 1; } @@ -207,7 +207,7 @@ chr = DICT_PROTOCOL_REPLY_FAIL; break; } - o_stream_send_str(conn->output, t_strdup_printf("%c\n", chr)); + o_stream_nsend_str(conn->output, t_strdup_printf("%c\n", chr)); dict_connection_transaction_array_remove(conn, trans); return 0; } @@ -231,7 +231,7 @@ } reply = t_strdup_printf("%c%c%u\n", DICT_PROTOCOL_REPLY_ASYNC_COMMIT, chr, trans->id); - o_stream_send_str(trans->conn->output, reply); + o_stream_nsend_str(trans->conn->output, reply); dict_connection_transaction_array_remove(trans->conn, trans); } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/dict/dict-connection.c --- a/src/dict/dict-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/dict/dict-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -149,6 +149,7 @@ conn->input = i_stream_create_fd(fd, DICT_CLIENT_MAX_LINE_LENGTH, FALSE); conn->output = o_stream_create_fd(fd, 128*1024, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); conn->io = io_add(fd, IO_READ, dict_connection_input, conn); DLLIST_PREPEND(&dict_connections, conn); return conn; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/director/auth-connection.c --- a/src/director/auth-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/director/auth-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -88,6 +88,7 @@ conn->input = i_stream_create_fd(conn->fd, AUTH_CLIENT_MAX_LINE_LENGTH, FALSE); conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); conn->io = io_add(conn->fd, IO_READ, auth_connection_input, conn); return 0; } @@ -125,7 +126,7 @@ { i_assert(conn->fd != -1); - (void)o_stream_send(conn->output, data, size); + o_stream_nsend(conn->output, data, size); } void auth_connections_deinit(void) diff -r 3ffdb4bf36d3 -r ca37d1577291 src/director/director-connection.c --- a/src/director/director-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/director/director-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -183,7 +183,6 @@ connect_str = t_strdup_printf("CONNECT\t%s\t%u\n", net_ip2addr(&host->ip), host->port); director_connection_send(conn, connect_str); - (void)o_stream_flush(conn->output); o_stream_uncork(conn->output); conn->to_disconnect = @@ -1388,6 +1387,7 @@ conn->dir = dir; conn->input = i_stream_create_fd(conn->fd, MAX_INBUF_SIZE, FALSE); conn->output = o_stream_create_fd(conn->fd, MAX_OUTBUF_SIZE, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); conn->to_ping = timeout_add(DIRECTOR_CONNECTION_ME_TIMEOUT_MSECS, director_connection_init_timeout, conn); array_append(&dir->connections, &conn, 1); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/director/director-test.c --- a/src/director/director-test.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/director/director-test.c Mon Jun 25 00:01:59 2012 +0300 @@ -194,22 +194,22 @@ if (!imap_arg_get_astring(args, &str)) return -1; - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, t_strconcat(tag, " OK Logged in.\r\n", NULL)); client->username = i_strdup(str); client_username_check(client); } else if (strcasecmp(cmd, "logout") == 0) { - o_stream_send_str(client->output, t_strconcat( + o_stream_nsend_str(client->output, t_strconcat( "* BYE Out.\r\n", tag, " OK Logged out.\r\n", NULL)); imap_client_destroy(&client); return 0; } else if (strcasecmp(cmd, "capability") == 0) { - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, t_strconcat("* CAPABILITY IMAP4rev1\r\n", tag, " OK Done.\r\n", NULL)); } else { - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, t_strconcat(tag, " BAD Not supported.\r\n", NULL)); } @@ -249,10 +249,11 @@ client->fd = fd; client->input = i_stream_create_fd(fd, 4096, FALSE); client->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); client->io = io_add(fd, IO_READ, imap_client_input, client); client->parser = imap_parser_create(client->input, client->output, 4096); - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, "* OK [CAPABILITY IMAP4rev1] director-test ready.\r\n"); DLLIST_PREPEND(&imap_clients, client); } @@ -277,8 +278,8 @@ DLLIST_REMOVE(&imap_clients, client); imap_parser_unref(&client->parser); io_remove(&client->io); - i_stream_unref(&client->input); - o_stream_unref(&client->output); + i_stream_destroy(&client->input); + o_stream_destroy(&client->output); net_disconnect(client->fd); i_free(client->username); i_free(client); @@ -298,7 +299,7 @@ return; } - o_stream_send(output, data, size); + o_stream_nsend(output, data, size); i_stream_skip(input, size); if (rand() % 3 == 0 && conn->to_delay == NULL) { @@ -345,12 +346,14 @@ conn->in_fd = in_fd; conn->in_input = i_stream_create_fd(conn->in_fd, (size_t)-1, FALSE); conn->in_output = o_stream_create_fd(conn->in_fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->in_output, TRUE); conn->in_io = io_add(conn->in_fd, IO_READ, director_connection_in_input, conn); conn->out_fd = out_fd; conn->out_input = i_stream_create_fd(conn->out_fd, (size_t)-1, FALSE); conn->out_output = o_stream_create_fd(conn->out_fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->out_output, TRUE); conn->out_io = io_add(conn->out_fd, IO_READ, director_connection_out_input, conn); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/director/doveadm-connection.c --- a/src/director/doveadm-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/director/doveadm-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -51,7 +51,7 @@ (*hostp)->user_count); } str_append_c(str, '\n'); - o_stream_send(conn->output, str_data(str), str_len(str)); + o_stream_nsend(conn->output, str_data(str), str_len(str)); } static void doveadm_cmd_host_list_removed(struct doveadm_connection *conn) @@ -87,7 +87,7 @@ for (; i < orig_hosts_count; i++) str_printfa(str, "%s\n", net_ip2addr(&orig_hosts[i]->ip)); str_append_c(str, '\n'); - o_stream_send(conn->output, str_data(str), str_len(str)); + o_stream_nsend(conn->output, str_data(str), str_len(str)); mail_hosts_deinit(&orig_hosts_list); } @@ -127,7 +127,7 @@ (unsigned long)last_failed); } str_append_c(str, '\n'); - o_stream_send(conn->output, str_data(str), str_len(str)); + o_stream_nsend(conn->output, str_data(str), str_len(str)); } static bool @@ -150,7 +150,7 @@ host = director_host_add(conn->dir, &ip, port); director_notify_ring_added(host, conn->dir->self_host); } - o_stream_send(conn->output, "OK\n", 3); + o_stream_nsend(conn->output, "OK\n", 3); return TRUE; } @@ -174,10 +174,10 @@ director_host_lookup(conn->dir, &ip, port) : director_host_lookup_ip(conn->dir, &ip); if (host == NULL) - o_stream_send_str(conn->output, "NOTFOUND\n"); + o_stream_nsend_str(conn->output, "NOTFOUND\n"); else { director_ring_remove(host, conn->dir->self_host); - o_stream_send(conn->output, "OK\n", 3); + o_stream_nsend(conn->output, "OK\n", 3); } return TRUE; } @@ -199,7 +199,7 @@ return FALSE; } if (vhost_count > MAX_VALID_VHOST_COUNT && vhost_count != -1U) { - o_stream_send_str(conn->output, "vhost count too large\n"); + o_stream_nsend_str(conn->output, "vhost count too large\n"); return TRUE; } host = mail_host_lookup(dir->mail_hosts, &ip); @@ -209,7 +209,7 @@ mail_host_set_vhost_count(dir->mail_hosts, host, vhost_count); director_update_host(dir, dir->self_host, NULL, host); - o_stream_send(conn->output, "OK\n", 3); + o_stream_nsend(conn->output, "OK\n", 3); return TRUE; } @@ -225,11 +225,11 @@ } host = mail_host_lookup(conn->dir->mail_hosts, &ip); if (host == NULL) - o_stream_send_str(conn->output, "NOTFOUND\n"); + o_stream_nsend_str(conn->output, "NOTFOUND\n"); else { director_remove_host(conn->dir, conn->dir->self_host, NULL, host); - o_stream_send(conn->output, "OK\n", 3); + o_stream_nsend(conn->output, "OK\n", 3); } return TRUE; } @@ -243,7 +243,7 @@ director_flush_host(conn->dir, conn->dir->self_host, NULL, *hostp); } - o_stream_send(conn->output, "OK\n", 3); + o_stream_nsend(conn->output, "OK\n", 3); } static bool @@ -263,11 +263,11 @@ } host = mail_host_lookup(conn->dir->mail_hosts, &ip); if (host == NULL) - o_stream_send_str(conn->output, "NOTFOUND\n"); + o_stream_nsend_str(conn->output, "NOTFOUND\n"); else { director_flush_host(conn->dir, conn->dir->self_host, NULL, host); - o_stream_send(conn->output, "OK\n", 3); + o_stream_nsend(conn->output, "OK\n", 3); } return TRUE; } @@ -307,7 +307,7 @@ str_append(str, "\t"); else str_printfa(str, "\t%s\n", net_ip2addr(&host->ip)); - o_stream_send(conn->output, str_data(str), str_len(str)); + o_stream_nsend(conn->output, str_data(str), str_len(str)); return TRUE; } @@ -334,14 +334,14 @@ unsigned int expire_time = user->timestamp + conn->dir->set->director_user_expire; - o_stream_send_str(conn->output, t_strdup_printf( + o_stream_nsend_str(conn->output, t_strdup_printf( "%u\t%u\t%s\n", user->username_hash, expire_time, net_ip2addr(&user->host->ip))); } T_END; } user_directory_iter_deinit(&iter); - o_stream_send(conn->output, "\n", 1); + o_stream_nsend(conn->output, "\n", 1); return TRUE; } @@ -362,7 +362,7 @@ } host = mail_host_lookup(conn->dir->mail_hosts, &ip); if (host == NULL) { - o_stream_send_str(conn->output, "NOTFOUND\n"); + o_stream_nsend_str(conn->output, "NOTFOUND\n"); return TRUE; } @@ -370,13 +370,13 @@ username_hash = user_directory_get_username_hash(conn->dir->users, line); user = user_directory_lookup(conn->dir->users, username_hash); if (user != NULL && user->kill_state != USER_KILL_STATE_NONE) { - o_stream_send_str(conn->output, "TRYAGAIN\n"); + o_stream_nsend_str(conn->output, "TRYAGAIN\n"); return TRUE; } director_move_user(conn->dir, conn->dir->self_host, NULL, username_hash, host); - o_stream_send(conn->output, "OK\n", 3); + o_stream_nsend(conn->output, "OK\n", 3); return TRUE; } @@ -453,8 +453,9 @@ conn->dir = dir; conn->input = i_stream_create_fd(conn->fd, 1024, FALSE); conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); conn->io = io_add(conn->fd, IO_READ, doveadm_connection_input, conn); - o_stream_send_str(conn->output, DOVEADM_HANDSHAKE); + o_stream_nsend_str(conn->output, DOVEADM_HANDSHAKE); DLLIST_PREPEND(&doveadm_connections, conn); return conn; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/director/login-connection.c --- a/src/director/login-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/director/login-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -67,7 +67,7 @@ iov[0].iov_len = strlen(line); iov[1].iov_base = "\n"; iov[1].iov_len = 1; - (void)o_stream_sendv(conn->output, iov, N_ELEMENTS(iov)); + o_stream_nsendv(conn->output, iov, N_ELEMENTS(iov)); } static void @@ -175,6 +175,7 @@ conn->auth = auth; conn->dir = dir; conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); conn->io = io_add(conn->fd, IO_READ, login_connection_input, conn); conn->userdb = userdb; @@ -195,7 +196,7 @@ DLLIST_REMOVE(&login_connections, conn); io_remove(&conn->io); - o_stream_unref(&conn->output); + o_stream_destroy(&conn->output); if (close(conn->fd) < 0) i_error("close(login connection) failed: %m"); conn->fd = -1; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/dns/dns-client.c --- a/src/dns/dns-client.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/dns/dns-client.c Mon Jun 25 00:01:59 2012 +0300 @@ -38,20 +38,20 @@ ret = NO_ADDRESS; } if (ret != 0) { - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, t_strdup_printf("%d\n", ret)); } else { - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, t_strdup_printf("0 %u\n", ips_count)); for (i = 0; i < ips_count; i++) { - o_stream_send_str(client->output, t_strconcat( + o_stream_nsend_str(client->output, t_strconcat( net_ip2addr(&ips[i]), "\n", NULL)); } } } else if (strcmp(line, "QUIT") == 0) { return -1; } else { - o_stream_send_str(client->output, "Unknown command\n"); + o_stream_nsend_str(client->output, "Unknown command\n"); } if (client->output->overflow) @@ -91,6 +91,7 @@ client->fd = fd; client->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); client->output = o_stream_create_fd(fd, MAX_OUTBUF_SIZE, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); client->io = io_add(fd, IO_READ, dns_client_input, client); client->to = timeout_add(INPUT_TIMEOUT_MSECS, dns_client_timeout, client); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/doveadm/client-connection.c --- a/src/doveadm/client-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/doveadm/client-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -127,14 +127,14 @@ if (ret < 0) { i_error("%s: %s", ctx->cmd->name, error); - o_stream_send(conn->output, "\n-\n", 3); + o_stream_nsend(conn->output, "\n-\n", 3); } else if (ret == 0) { - o_stream_send_str(conn->output, "\n-NOUSER\n"); + o_stream_nsend_str(conn->output, "\n-NOUSER\n"); } else if (ctx->exit_code != 0) { /* maybe not an error, but not a full success either */ - o_stream_send(conn->output, "\n-\n", 3); + o_stream_nsend(conn->output, "\n-\n", 3); } else { - o_stream_send(conn->output, "\n+\n", 3); + o_stream_nsend(conn->output, "\n+\n", 3); } pool_unref(&ctx->pool); } @@ -211,7 +211,7 @@ o_stream_cork(conn->output); ctx = doveadm_mail_cmd_server_parse(cmd_name, conn->set, &input, argc, args); if (ctx == NULL) - o_stream_send(conn->output, "\n-\n", 3); + o_stream_nsend(conn->output, "\n-\n", 3); else doveadm_mail_cmd_server_run(conn, ctx, &input); o_stream_uncork(conn->output); @@ -293,12 +293,12 @@ if (!conn->authenticated) { if ((ret = client_connection_authenticate(conn)) <= 0) { if (ret < 0) { - o_stream_send(conn->output, "-\n", 2); + o_stream_nsend(conn->output, "-\n", 2); client_connection_destroy(&conn); } return; } - o_stream_send(conn->output, "+\n", 2); + o_stream_nsend(conn->output, "+\n", 2); conn->authenticated = TRUE; } @@ -356,6 +356,7 @@ conn->io = io_add(fd, IO_READ, client_connection_input, conn); conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); (void)net_getsockname(fd, &conn->local_ip, &port); (void)net_getpeername(fd, &conn->remote_ip, &port); @@ -367,9 +368,9 @@ (st.st_mode & 0777) == 0600) { /* no need for client to authenticate */ conn->authenticated = TRUE; - o_stream_send(conn->output, "+\n", 2); + o_stream_nsend(conn->output, "+\n", 2); } else { - o_stream_send(conn->output, "-\n", 2); + o_stream_nsend(conn->output, "-\n", 2); } if (client_connection_read_settings(conn) < 0) client_connection_destroy(&conn); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/doveadm/doveadm-mail-fetch.c --- a/src/doveadm/doveadm-mail-fetch.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/doveadm/doveadm-mail-fetch.c Mon Jun 25 00:01:59 2012 +0300 @@ -562,6 +562,7 @@ _ctx->search_args = doveadm_mail_build_search_args(args + 1); ctx->output = o_stream_create_fd(STDOUT_FILENO, 0, FALSE); + o_stream_set_no_error_handling(ctx->output, TRUE); } static struct doveadm_mail_cmd_context *cmd_fetch_alloc(void) diff -r 3ffdb4bf36d3 -r ca37d1577291 src/doveadm/doveadm-print-server.c --- a/src/doveadm/doveadm-print-server.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/doveadm/doveadm-print-server.c Mon Jun 25 00:01:59 2012 +0300 @@ -68,8 +68,8 @@ if (doveadm_client == NULL) return; - o_stream_send(client_connection_get_output(doveadm_client), - str_data(ctx.str), str_len(ctx.str)); + o_stream_nsend(client_connection_get_output(doveadm_client), + str_data(ctx.str), str_len(ctx.str)); str_truncate(ctx.str, 0); } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/doveadm/dsync/dsync-slave-io.c --- a/src/doveadm/dsync/dsync-slave-io.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/doveadm/dsync/dsync-slave-io.c Mon Jun 25 00:01:59 2012 +0300 @@ -201,7 +201,7 @@ } if (i > 0) { - (void)o_stream_send(slave->output, data, i); + o_stream_nsend(slave->output, data, i); slave->mail_output_last = data[i-1]; i_stream_skip(slave->mail_output, i); } @@ -219,7 +219,7 @@ } if (add != '\0') { - (void)o_stream_send(slave->output, &add, 1); + o_stream_nsend(slave->output, &add, 1); slave->mail_output_last = add; } } @@ -233,7 +233,7 @@ } /* finished sending the stream */ - (void)o_stream_send_str(slave->output, "\r\n.\r\n"); + o_stream_nsend_str(slave->output, "\r\n.\r\n"); i_stream_unref(&slave->mail_output); return 1; } @@ -273,11 +273,12 @@ slave->input = i_stream_create_fd(slave->fd_in, (size_t)-1, FALSE); slave->output = o_stream_create_fd(slave->fd_out, (size_t)-1, FALSE); slave->io = io_add(slave->fd_in, IO_READ, dsync_slave_io_input, slave); + o_stream_set_no_error_handling(slave->output, TRUE); o_stream_set_flush_callback(slave->output, dsync_slave_io_output, slave); slave->to = timeout_add(DSYNC_SLAVE_IO_TIMEOUT_MSECS, dsync_slave_io_timeout, slave); o_stream_cork(slave->output); - o_stream_send_str(slave->output, DSYNC_HANDSHAKE_VERSION); + o_stream_nsend_str(slave->output, DSYNC_HANDSHAKE_VERSION); /* initialize serializers and send their headers to remote */ for (i = 1; i < ITEM_END_OF_LIST; i++) T_BEGIN { @@ -291,12 +292,12 @@ slave->serializers[i] = dsync_serializer_init(t_strsplit_spaces(keys, " ")); - o_stream_send(slave->output, &items[i].chr, 1); - o_stream_send_str(slave->output, + o_stream_nsend(slave->output, &items[i].chr, 1); + o_stream_nsend_str(slave->output, dsync_serializer_encode_header_line(slave->serializers[i])); } } T_END; - o_stream_send_str(slave->output, ".\n"); + o_stream_nsend_str(slave->output, ".\n"); dsync_slave_flush(&slave->slave); } @@ -387,7 +388,7 @@ dsync_slave_io_send_string(struct dsync_slave_io *slave, const string_t *str) { i_assert(slave->mail_output == NULL); - o_stream_send(slave->output, str_data(str), str_len(str)); + o_stream_nsend(slave->output, str_data(str), str_len(str)); } static int dsync_slave_check_missing_deserializers(struct dsync_slave_io *slave) @@ -607,7 +608,7 @@ i_assert(slave->mail_output == NULL); - o_stream_send_str(slave->output, END_OF_LIST_LINE"\n"); + o_stream_nsend_str(slave->output, END_OF_LIST_LINE"\n"); } static void diff -r 3ffdb4bf36d3 -r ca37d1577291 src/doveadm/server-connection.c --- a/src/doveadm/server-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/doveadm/server-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -162,7 +162,7 @@ { conn->authenticated = TRUE; if (conn->delayed_cmd != NULL) { - o_stream_send_str(conn->output, conn->delayed_cmd); + o_stream_nsend_str(conn->output, conn->delayed_cmd); conn->delayed_cmd = NULL; } } @@ -188,7 +188,7 @@ base64_encode(plain->data, plain->used, cmd); str_append_c(cmd, '\n'); - o_stream_send(conn->output, cmd->data, cmd->used); + o_stream_nsend(conn->output, cmd->data, cmd->used); return 0; } @@ -319,8 +319,9 @@ conn->io = io_add(conn->fd, IO_READ, server_connection_input, conn); conn->input = i_stream_create_fd(conn->fd, MAX_INBUF_SIZE, FALSE); conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); conn->state = SERVER_REPLY_STATE_DONE; - o_stream_send_str(conn->output, DOVEADM_SERVER_HANDSHAKE); + o_stream_nsend_str(conn->output, DOVEADM_SERVER_HANDSHAKE); array_append(&conn->server->connections, &conn, 1); server_connection_read_settings(conn); @@ -372,7 +373,7 @@ conn->state = SERVER_REPLY_STATE_PRINT; if (conn->authenticated) - o_stream_send_str(conn->output, line); + o_stream_nsend_str(conn->output, line); else conn->delayed_cmd = p_strdup(conn->pool, line); conn->callback = callback; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/imap-login/imap-proxy.c --- a/src/imap-login/imap-proxy.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/imap-login/imap-proxy.c Mon Jun 25 00:01:59 2012 +0300 @@ -130,7 +130,7 @@ proxy_write_login(client, str); } - (void)o_stream_send(output, str_data(str), str_len(str)); + o_stream_nsend(output, str_data(str), str_len(str)); return 0; } @@ -201,7 +201,7 @@ str_append(str, "\r\n"); proxy_free_password(client); - (void)o_stream_send(output, str_data(str), str_len(str)); + o_stream_nsend(output, str_data(str), str_len(str)); return 0; } else if (strncmp(line, "S ", 2) == 0) { if (strncmp(line, "S OK ", 5) != 0) { @@ -222,15 +222,14 @@ output = login_proxy_get_ostream(client->login_proxy); str = t_str_new(128); proxy_write_login(imap_client, str); - (void)o_stream_send(output, str_data(str), str_len(str)); + o_stream_nsend(output, str_data(str), str_len(str)); return 1; } else if (strncmp(line, "L OK ", 5) == 0) { /* Login successful. Send this line to client. */ client->proxy_state = IMAP_PROXY_STATE_LOGIN; str = t_str_new(128); client_send_login_reply(imap_client, str, line + 5); - (void)o_stream_send(client->output, - str_data(str), str_len(str)); + o_stream_nsend(client->output, str_data(str), str_len(str)); (void)client_skip_line(imap_client); client_proxy_finish_destroy_client(client); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/imap/cmd-append.c --- a/src/imap/cmd-append.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/imap/cmd-append.c Mon Jun 25 00:01:59 2012 +0300 @@ -418,8 +418,8 @@ client->input_skip_line = TRUE; if (!nonsync) { - o_stream_send(client->output, "+ OK\r\n", 6); - o_stream_flush(client->output); + o_stream_nsend(client->output, "+ OK\r\n", 6); + o_stream_nflush(client->output); o_stream_uncork(client->output); o_stream_cork(client->output); } @@ -698,8 +698,8 @@ } if (!nonsync) { - o_stream_send(client->output, "+ OK\r\n", 6); - o_stream_flush(client->output); + o_stream_nsend(client->output, "+ OK\r\n", 6); + o_stream_nflush(client->output); o_stream_uncork(client->output); o_stream_cork(client->output); } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/imap/cmd-copy.c --- a/src/imap/cmd-copy.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/imap/cmd-copy.c Mon Jun 25 00:01:59 2012 +0300 @@ -22,8 +22,8 @@ now = time(NULL); last_io = I_MAX(client->last_input, client->last_output); if (now - last_io > MAIL_STORAGE_STAYALIVE_SECS) { - o_stream_send_str(client->output, "* OK Hang in there..\r\n"); - o_stream_flush(client->output); + o_stream_nsend_str(client->output, "* OK Hang in there..\r\n"); + o_stream_nflush(client->output); client->last_output = now; } } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/imap/cmd-thread.c --- a/src/imap/cmd-thread.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/imap/cmd-thread.c Mon Jun 25 00:01:59 2012 +0300 @@ -94,10 +94,8 @@ mail_thread_deinit(&ctx); } - if (ret == 0) { - (void)o_stream_send(cmd->client->output, - str_data(str), str_len(str)); - } + if (ret == 0) + o_stream_nsend(cmd->client->output, str_data(str), str_len(str)); str_free(&str); return ret; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/imap/imap-client.c --- a/src/imap/imap-client.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/imap/imap-client.c Mon Jun 25 00:01:59 2012 +0300 @@ -59,6 +59,7 @@ client->input = i_stream_create_fd(fd_in, set->imap_max_line_length, FALSE); client->output = o_stream_create_fd(fd_out, (size_t)-1, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); o_stream_set_flush_callback(client->output, client_output, client); @@ -267,7 +268,7 @@ i_info("Disconnected: %s %s", reason, client_stats(client)); client->disconnected = TRUE; - (void)o_stream_flush(client->output); + o_stream_nflush(client->output); o_stream_uncork(client->output); i_stream_close(client->input); @@ -319,10 +320,10 @@ if (tag == NULL || *tag == '\0') tag = "*"; - (void)o_stream_send_str(client->output, tag); - (void)o_stream_send(client->output, " ", 1); - (void)o_stream_send_str(client->output, data); - (void)o_stream_send(client->output, "\r\n", 2); + o_stream_nsend_str(client->output, tag); + o_stream_nsend(client->output, " ", 1); + o_stream_nsend_str(client->output, data); + o_stream_nsend(client->output, "\r\n", 2); client->last_output = ioloop_time; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/imap/imap-fetch-body.c --- a/src/imap/imap-fetch-body.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/imap/imap-fetch-body.c Mon Jun 25 00:01:59 2012 +0300 @@ -124,8 +124,7 @@ ctx->cur_name = p_strconcat(ctx->pool, "[", body->section, "]", NULL); str = get_prefix(ctx, body, ctx->cur_size); - if (o_stream_send(ctx->client->output, str_data(str), str_len(str)) < 0) - return -1; + o_stream_nsend(ctx->client->output, str_data(str), str_len(str)); ctx->cont_handler = fetch_stream_continue; return ctx->cont_handler(ctx); @@ -340,8 +339,7 @@ if (ctx->first) { str++; ctx->first = FALSE; } - if (o_stream_send_str(ctx->client->output, str) < 0) - return -1; + o_stream_nsend_str(ctx->client->output, str); ctx->cur_name = "RFC822"; return ctx->cont_handler(ctx); @@ -362,8 +360,7 @@ if (ctx->first) { str++; ctx->first = FALSE; } - if (o_stream_send_str(ctx->client->output, str) < 0) - return -1; + o_stream_nsend_str(ctx->client->output, str); ctx->cur_name = "RFC822.HEADER"; return ctx->cont_handler(ctx); @@ -384,8 +381,7 @@ if (ctx->first) { str++; ctx->first = FALSE; } - if (o_stream_send_str(ctx->client->output, str) < 0) - return -1; + o_stream_nsend_str(ctx->client->output, str); ctx->cur_name = "RFC822.TEXT"; return ctx->cont_handler(ctx); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/imap/imap-fetch.c --- a/src/imap/imap-fetch.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/imap/imap-fetch.c Mon Jun 25 00:01:59 2012 +0300 @@ -318,7 +318,7 @@ str_append(str, "* VANISHED (EARLIER) "); imap_write_seq_range(str, &expunged_uids_range); str_append(str, "\r\n"); - o_stream_send(ctx->client->output, str_data(str), str_len(str)); + o_stream_nsend(ctx->client->output, str_data(str), str_len(str)); str_free(&str); } array_free(&expunged_uids_range); @@ -521,8 +521,7 @@ ctx->line_finished = TRUE; ctx->line_partial = FALSE; - if (o_stream_send(client->output, ")\r\n", 3) < 0) - return -1; + o_stream_nsend(client->output, ")\r\n", 3); client->last_output = ioloop_time; ctx->cur_mail = NULL; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/imap/imap-search.c --- a/src/imap/imap-search.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/imap/imap-search.c Mon Jun 25 00:01:59 2012 +0300 @@ -177,8 +177,8 @@ for (seq = range->seq1; seq <= range->seq2; seq++) str_printfa(str, " %u", seq); if (str_len(str) >= 1024-32) { - o_stream_send(ctx->cmd->client->output, - str_data(str), str_len(str)); + o_stream_nsend(ctx->cmd->client->output, + str_data(str), str_len(str)); str_truncate(str, 0); } } @@ -188,8 +188,7 @@ (unsigned long long)ctx->highest_seen_modseq); } str_append(str, "\r\n"); - o_stream_send(ctx->cmd->client->output, - str_data(str), str_len(str)); + o_stream_nsend(ctx->cmd->client->output, str_data(str), str_len(str)); } static void @@ -318,7 +317,7 @@ (unsigned long long)ctx->highest_seen_modseq); } str_append(str, "\r\n"); - o_stream_send(client->output, str_data(str), str_len(str)); + o_stream_nsend(client->output, str_data(str), str_len(str)); str_free(&str); } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/imap/imap-sync.c --- a/src/imap/imap-sync.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/imap/imap-sync.c Mon Jun 25 00:01:59 2012 +0300 @@ -102,7 +102,7 @@ str_append_c(cmd, ')'); } str_append(cmd, "\r\n"); - o_stream_send(ctx->client->output, str_data(cmd), str_len(cmd)); + o_stream_nsend(ctx->client->output, str_data(cmd), str_len(cmd)); } static void imap_sync_send_search_updates(struct imap_sync_context *ctx) @@ -366,7 +366,7 @@ str_printfa(line, ":%u", prev_uid); } str_append(line, "\r\n"); - o_stream_send(ctx->client->output, str_data(line), str_len(line)); + o_stream_nsend(ctx->client->output, str_data(line), str_len(line)); } int imap_sync_more(struct imap_sync_context *ctx) diff -r 3ffdb4bf36d3 -r ca37d1577291 src/imap/mail-storage-callbacks.c --- a/src/imap/mail-storage-callbacks.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/imap/mail-storage-callbacks.c Mon Jun 25 00:01:59 2012 +0300 @@ -17,8 +17,8 @@ const char *str; str = t_strconcat("* OK ", text, "\r\n", NULL); - o_stream_send_str(client->output, str); - o_stream_flush(client->output); + o_stream_nsend_str(client->output, str); + (void)o_stream_flush(client->output); } T_END; } @@ -34,8 +34,8 @@ const char *str; str = t_strconcat("* NO ", text, "\r\n", NULL); - o_stream_send_str(client->output, str); - o_stream_flush(client->output); + o_stream_nsend_str(client->output, str); + (void)o_stream_flush(client->output); } T_END; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/indexer/indexer-client.c --- a/src/indexer/indexer-client.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/indexer/indexer-client.c Mon Jun 25 00:01:59 2012 +0300 @@ -94,7 +94,7 @@ indexer_queue_append(client->queue, append, args[1], args[2], max_recent_msgs, ctx); - o_stream_send_str(client->output, t_strdup_printf("%u\tOK\n", tag)); + o_stream_nsend_str(client->output, t_strdup_printf("%u\tOK\n", tag)); return 0; } @@ -123,7 +123,7 @@ } indexer_queue_append_optimize(client->queue, args[1], args[2], ctx); - o_stream_send_str(client->output, t_strdup_printf("%u\tOK\n", tag)); + o_stream_nsend_str(client->output, t_strdup_printf("%u\tOK\n", tag)); return 0; } @@ -192,7 +192,7 @@ struct indexer_client_request *ctx = context; T_BEGIN { - o_stream_send_str(ctx->client->output, + o_stream_nsend_str(ctx->client->output, t_strdup_printf("%u\t%d\n", ctx->tag, percentage)); } T_END; if (percentage < 0 || percentage == 100) { @@ -212,6 +212,7 @@ client->fd = fd; client->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); client->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); client->io = io_add(fd, IO_READ, indexer_client_input, client); DLLIST_PREPEND(&clients, client); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/indexer/worker-connection.c --- a/src/indexer/worker-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/indexer/worker-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -198,7 +198,8 @@ conn->io = io_add(conn->fd, IO_READ, worker_connection_input, conn); conn->input = i_stream_create_fd(conn->fd, (size_t)-1, FALSE); conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE); - o_stream_send_str(conn->output, INDEXER_MASTER_HANDSHAKE); + o_stream_set_no_error_handling(conn->output, TRUE); + o_stream_nsend_str(conn->output, INDEXER_MASTER_HANDSHAKE); return 0; } @@ -246,7 +247,7 @@ if (request->optimize) str_append_c(str, 'o'); str_append_c(str, '\n'); - o_stream_send(conn->output, str_data(str), str_len(str)); + o_stream_nsend(conn->output, str_data(str), str_len(str)); } T_END; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/ipc/client.c --- a/src/ipc/client.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/ipc/client.c Mon Jun 25 00:01:59 2012 +0300 @@ -44,8 +44,8 @@ } T_BEGIN { - o_stream_send_str(client->output, - t_strdup_printf("%c%s\n", chr, line)); + o_stream_nsend_str(client->output, + t_strdup_printf("%c%s\n", chr, line)); } T_END; if (status != IPC_CMD_STATUS_REPLY && client->io == NULL) { @@ -72,7 +72,7 @@ data = strchr(id, '\t'); } if (data == NULL || data[1] == '\0') { - o_stream_send_str(client->output, "-Invalid input\n"); + o_stream_nsend_str(client->output, "-Invalid input\n"); continue; } *data++ = '\0'; @@ -89,14 +89,14 @@ client_cmd_input, client); } } else if (str_to_uint(id, &id_num) < 0) { - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, t_strdup_printf("-Invalid IPC connection id: %s\n", id)); continue; } else if (group == NULL) { - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, t_strdup_printf("-Unknown IPC group: %s\n", line)); } else if ((conn = ipc_connection_lookup_id(group, id_num)) == NULL) { - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, t_strdup_printf("-Unknown IPC connection id: %u\n", id_num)); continue; } else { @@ -124,6 +124,7 @@ client->io = io_add(fd, IO_READ, client_input, client); client->input = i_stream_create_fd(fd, (size_t)-1, FALSE); client->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); DLLIST_PREPEND(&clients, client); return client; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/ipc/ipc-connection.c --- a/src/ipc/ipc-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/ipc/ipc-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -177,8 +177,9 @@ conn->io = io_add(fd, IO_READ, ipc_connection_input, conn); conn->input = i_stream_create_fd(fd, (size_t)-1, FALSE); conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); i_array_init(&conn->cmds, 8); - o_stream_send_str(conn->output, IPC_SERVER_HANDSHAKE); + o_stream_nsend_str(conn->output, IPC_SERVER_HANDSHAKE); DLLIST_PREPEND(&conn->group->connections, conn); return conn; @@ -236,7 +237,7 @@ array_append(&conn->cmds, &ipc_cmd, 1); T_BEGIN { - o_stream_send_str(conn->output, + o_stream_nsend_str(conn->output, t_strdup_printf("%u\t%s\n", ipc_cmd->tag, cmd)); } T_END; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-auth/auth-master.c --- a/src/lib-auth/auth-master.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-auth/auth-master.c Mon Jun 25 00:01:59 2012 +0300 @@ -397,15 +397,14 @@ if (!conn->sent_handshake) { str = t_strdup_printf("VERSION\t%d\t%d\n", AUTH_PROTOCOL_MAJOR, AUTH_PROTOCOL_MINOR); - o_stream_send_str(conn->output, str); + o_stream_nsend_str(conn->output, str); conn->sent_handshake = TRUE; } - o_stream_send_str(conn->output, cmd); + o_stream_nsend_str(conn->output, cmd); o_stream_uncork(conn->output); - if (conn->output->stream_errno != 0) { - errno = conn->output->stream_errno; + if (o_stream_nfinish(conn->output) < 0) { i_error("write(auth socket) failed: %m"); conn->aborted = TRUE; } else { diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-dict/dict-file.c --- a/src/lib-dict/dict-file.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-dict/dict-file.c Mon Jun 25 00:01:59 2012 +0300 @@ -512,15 +512,14 @@ o_stream_cork(output); iter = hash_table_iterate_init(dict->hash); while (hash_table_iterate(iter, &key, &value)) { - (void)o_stream_send_str(output, key); - (void)o_stream_send(output, "\n", 1); - (void)o_stream_send_str(output, value); - (void)o_stream_send(output, "\n", 1); + o_stream_nsend_str(output, key); + o_stream_nsend(output, "\n", 1); + o_stream_nsend_str(output, value); + o_stream_nsend(output, "\n", 1); } - o_stream_uncork(output); hash_table_iterate_deinit(&iter); - if (output->stream_errno != 0) { + if (o_stream_nfinish(output) < 0) { i_error("write(%s) failed: %m", temp_path); o_stream_destroy(&output); (void)close(fd); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-fs/fs-posix.c --- a/src/lib-fs/fs-posix.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-fs/fs-posix.c Mon Jun 25 00:01:59 2012 +0300 @@ -349,9 +349,7 @@ struct posix_fs_file *file = (struct posix_fs_file *)_file; int ret = success ? 0 : -1; - (void)o_stream_flush(_file->output); - if (_file->output->last_failed_errno < 0) { - errno = _file->output->last_failed_errno; + if (o_stream_nfinish(_file->output) < 0) { fs_set_error(_file->fs, "write(%s) failed: %m", o_stream_get_name(_file->output)); ret = -1; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-fs/ostream-cmp.c --- a/src/lib-fs/ostream-cmp.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-fs/ostream-cmp.c Mon Jun 25 00:01:59 2012 +0300 @@ -20,7 +20,7 @@ return; i_stream_unref(&cstream->input); - o_stream_flush(&cstream->ostream.ostream); + (void)o_stream_flush(&cstream->ostream.ostream); } bool stream_cmp_block(struct istream *input, diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-imap-client/imapc-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -1294,6 +1294,7 @@ conn->fd = fd; conn->input = conn->raw_input = i_stream_create_fd(fd, (size_t)-1, FALSE); conn->output = conn->raw_output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); if (*conn->client->set.rawlog_dir != '\0' && conn->client->set.ssl_mode != IMAPC_CLIENT_SSL_MODE_IMMEDIATE && @@ -1627,7 +1628,7 @@ data = CONST_PTR_OFFSET(cmd->data->data, cmd->send_pos); size = end_pos - cmd->send_pos; - o_stream_send(conn->output, data, size); + o_stream_nsend(conn->output, data, size); cmd->send_pos = end_pos; if (cmd->send_pos == cmd->data->used) { @@ -1656,7 +1657,7 @@ { if ((conn->idling || conn->idle_plus_waiting) && !conn->idle_stopping) { conn->idle_stopping = TRUE; - o_stream_send_str(conn->output, "DONE\r\n"); + o_stream_nsend_str(conn->output, "DONE\r\n"); } } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-imap/imap-parser.c --- a/src/lib-imap/imap-parser.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-imap/imap-parser.c Mon Jun 25 00:01:59 2012 +0300 @@ -372,8 +372,8 @@ } if (parser->output != NULL && !parser->literal_nonsync) { - o_stream_send(parser->output, "+ OK\r\n", 6); - o_stream_flush(parser->output); + o_stream_nsend(parser->output, "+ OK\r\n", 6); + o_stream_nflush(parser->output); } } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-index/mail-cache-compress.c --- a/src/lib-index/mail-cache-compress.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-index/mail-cache-compress.c Mon Jun 25 00:01:59 2012 +0300 @@ -176,7 +176,7 @@ hdr.compat_sizeof_uoff_t = sizeof(uoff_t); hdr.indexid = cache->index->indexid; hdr.file_seq = get_next_file_seq(cache, view); - o_stream_send(output, &hdr, sizeof(hdr)); + o_stream_nsend(output, &hdr, sizeof(hdr)); memset(&ctx, 0, sizeof(ctx)); ctx.cache = cache; @@ -262,7 +262,7 @@ ext_offset = output->offset; buffer_write(ctx.buffer, 0, &cache_rec, sizeof(cache_rec)); - o_stream_send(output, ctx.buffer->data, cache_rec.size); + o_stream_nsend(output, ctx.buffer->data, cache_rec.size); } array_append(ext_offsets, &ext_offset, 1); @@ -271,20 +271,19 @@ hdr.field_header_offset = mail_index_uint32_to_offset(output->offset); mail_cache_compress_get_fields(&ctx, used_fields_count); - o_stream_send(output, ctx.buffer->data, ctx.buffer->used); + o_stream_nsend(output, ctx.buffer->data, ctx.buffer->used); hdr.used_file_size = output->offset; buffer_free(&ctx.buffer); buffer_free(&ctx.field_seen); o_stream_seek(output, 0); - o_stream_send(output, &hdr, sizeof(hdr)); + o_stream_nsend(output, &hdr, sizeof(hdr)); mail_cache_view_close(&cache_view); - if (o_stream_flush(output) < 0) { - errno = output->stream_errno; - mail_cache_set_syscall_error(cache, "o_stream_flush()"); + if (o_stream_nfinish(output) < 0) { + mail_cache_set_syscall_error(cache, "write()"); o_stream_destroy(&output); array_free(ext_offsets); return -1; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-index/mail-index-strmap.c --- a/src/lib-index/mail-index-strmap.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-index/mail-index-strmap.c Mon Jun 25 00:01:59 2012 +0300 @@ -884,9 +884,9 @@ i_free(renumber_map); } -static int mail_index_strmap_write_block(struct mail_index_strmap_view *view, - struct ostream *output, - unsigned int i, uint32_t base_uid) +static void mail_index_strmap_write_block(struct mail_index_strmap_view *view, + struct ostream *output, + unsigned int i, uint32_t base_uid) { const struct mail_index_strmap_rec *recs; const uint32_t *crc32; @@ -898,7 +898,7 @@ /* skip over the block size for now, we don't know it yet */ block_offset = output->offset; block_size = 0; - o_stream_send(output, &block_size, sizeof(block_size)); + o_stream_nsend(output, &block_size, sizeof(block_size)); /* write records */ recs = array_get(&view->recs, &count); @@ -936,13 +936,13 @@ } mail_index_pack_num(&p, n); - o_stream_send(output, packed, p-packed); + o_stream_nsend(output, packed, p-packed); for (j = 0; j < uid_rec_count; j++) - o_stream_send(output, &crc32[i+j], sizeof(crc32[i+j])); + o_stream_nsend(output, &crc32[i+j], sizeof(crc32[i+j])); for (j = 0; j < uid_rec_count; j++) { i_assert(j < 2 || recs[i+j].ref_index == j+1); - o_stream_send(output, &recs[i+j].str_idx, - sizeof(recs[i+j].str_idx)); + o_stream_nsend(output, &recs[i+j].str_idx, + sizeof(recs[i+j].str_idx)); } i += uid_rec_count; } @@ -954,17 +954,15 @@ end_offset = output->offset; o_stream_seek(output, block_offset); - o_stream_send(output, &block_size, sizeof(block_size)); + o_stream_nsend(output, &block_size, sizeof(block_size)); o_stream_seek(output, end_offset); if (output->last_failed_errno != 0) - return -1; - else { - i_assert(view->last_added_uid == recs[count-1].uid); - view->last_read_uid = recs[count-1].uid; - view->last_read_block_offset = output->offset; - return 0; - } + return; + + i_assert(view->last_added_uid == recs[count-1].uid); + view->last_read_uid = recs[count-1].uid; + view->last_read_block_offset = output->offset; } static void @@ -980,10 +978,10 @@ memset(&hdr, 0, sizeof(hdr)); hdr.version = MAIL_INDEX_STRMAP_VERSION; hdr.uid_validity = idx_hdr->uid_validity; - o_stream_send(output, &hdr, sizeof(hdr)); + o_stream_nsend(output, &hdr, sizeof(hdr)); view->total_ref_count = 0; - (void)mail_index_strmap_write_block(view, output, 0, 1); + mail_index_strmap_write_block(view, output, 0, 1); } static int mail_index_strmap_recreate(struct mail_index_strmap_view *view) @@ -1017,8 +1015,7 @@ output = o_stream_create_fd(fd, 0, FALSE); o_stream_cork(output); mail_index_strmap_recreate_write(view, output); - if (output->last_failed_errno != 0) { - errno = output->last_failed_errno; + if (o_stream_nfinish(output) < 0) { mail_index_set_error(strmap->index, "write(%s) failed: %m", temp_path); ret = -1; @@ -1172,9 +1169,9 @@ output = o_stream_create_fd(view->strmap->fd, 0, FALSE); o_stream_seek(output, view->last_read_block_offset); o_stream_cork(output); - if (mail_index_strmap_write_block(view, output, i, - view->last_read_uid + 1) < 0) { - errno = output->last_failed_errno; + mail_index_strmap_write_block(view, output, i, + view->last_read_uid + 1); + if (o_stream_nfinish(output) < 0) { mail_index_strmap_set_syscall_error(view->strmap, "write()"); ret = -1; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-index/mail-index-write.c --- a/src/lib-index/mail-index-write.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-index/mail-index-write.c Mon Jun 25 00:01:59 2012 +0300 @@ -76,13 +76,13 @@ o_stream_cork(output); base_size = I_MIN(map->hdr.base_header_size, sizeof(map->hdr)); - if (o_stream_send(output, &map->hdr, base_size) < 0 || - o_stream_send(output, CONST_PTR_OFFSET(map->hdr_base, base_size), - map->hdr.header_size - base_size) < 0 || - o_stream_send(output, map->rec_map->records, - map->rec_map->records_count * - map->hdr.record_size) < 0 || - o_stream_flush(output) < 0) { + o_stream_nsend(output, &map->hdr, base_size); + o_stream_nsend(output, CONST_PTR_OFFSET(map->hdr_base, base_size), + map->hdr.header_size - base_size); + o_stream_nsend(output, map->rec_map->records, + map->rec_map->records_count * map->hdr.record_size); + o_stream_nflush(output); + if (o_stream_nfinish(output) < 0) { mail_index_file_set_syscall_error(index, path, "write()"); ret = -1; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-lda/duplicate.c --- a/src/lib-lda/duplicate.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-lda/duplicate.c Mon Jun 25 00:01:59 2012 +0300 @@ -297,7 +297,7 @@ output = o_stream_create_fd_file(file->new_fd, 0, FALSE); o_stream_cork(output); - (void)o_stream_send(output, &hdr, sizeof(hdr)); + o_stream_nsend(output, &hdr, sizeof(hdr)); memset(&rec, 0, sizeof(rec)); iter = hash_table_iterate_init(file->hash); @@ -308,15 +308,13 @@ rec.id_size = d->id_size; rec.user_size = strlen(d->user); - (void)o_stream_send(output, &rec, sizeof(rec)); - (void)o_stream_send(output, d->id, rec.id_size); - (void)o_stream_send(output, d->user, rec.user_size); + o_stream_nsend(output, &rec, sizeof(rec)); + o_stream_nsend(output, d->id, rec.id_size); + o_stream_nsend(output, d->user, rec.user_size); } - o_stream_uncork(output); hash_table_iterate_deinit(&iter); - if (output->last_failed_errno != 0) { - errno = output->last_failed_errno; + if (o_stream_nfinish(output) < 0) { i_error("write(%s) failed: %m", file->path); o_stream_unref(&output); file_dotlock_delete(&file->dotlock); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-lda/lmtp-client.c --- a/src/lib-lda/lmtp-client.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-lda/lmtp-client.c Mon Jun 25 00:01:59 2012 +0300 @@ -252,7 +252,7 @@ return -1; } else { client->input_state++; - o_stream_send_str(client->output, "DATA\r\n"); + o_stream_nsend_str(client->output, "DATA\r\n"); return 0; } } @@ -349,9 +349,9 @@ if (client->output_last != '\n') { /* didn't end with CRLF */ - (void)o_stream_send(client->output, "\r\n", 2); + o_stream_nsend(client->output, "\r\n", 2); } - (void)o_stream_send(client->output, ".\r\n", 3); + o_stream_nsend(client->output, ".\r\n", 3); client->output_finished = TRUE; } @@ -359,12 +359,12 @@ { switch (client->protocol) { case LMTP_CLIENT_PROTOCOL_LMTP: - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, t_strdup_printf("LHLO %s\r\n", client->set.my_hostname)); break; case LMTP_CLIENT_PROTOCOL_SMTP: - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, t_strdup_printf("EHLO %s\r\n", client->set.my_hostname)); break; @@ -440,7 +440,7 @@ return FALSE; str_append(str, "\r\n"); - o_stream_send(client->output, str_data(str), str_len(str)); + o_stream_nsend(client->output, str_data(str), str_len(str)); return TRUE; } @@ -482,7 +482,7 @@ break; } if (client->input_state == LMTP_INPUT_STATE_LHLO) { - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, t_strdup_printf("MAIL FROM:%s\r\n", client->set.mail_from)); } @@ -504,7 +504,7 @@ } client->input_state++; if (client->data_header != NULL) - o_stream_send_str(client->output, client->data_header); + o_stream_nsend_str(client->output, client->data_header); lmtp_client_send_data(client); break; case LMTP_INPUT_STATE_DATA: @@ -593,6 +593,7 @@ client->input = i_stream_create_fd(client->fd, LMTP_MAX_LINE_LEN, FALSE); client->output = o_stream_create_fd(client->fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); o_stream_set_flush_callback(client->output, lmtp_client_output, client); /* we're already sending data in ostream, so can't use IO_WRITE here */ client->io = io_add(client->fd, IO_READ, @@ -679,7 +680,7 @@ rcpt = array_get(&client->recipients, &count); for (i = client->rcpt_next_send_idx; i < count; i++) { - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, t_strdup_printf("RCPT TO:<%s>\r\n", rcpt[i].address)); } client->rcpt_next_send_idx = i; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-lda/mail-send.c --- a/src/lib-lda/mail-send.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-lda/mail-send.c Mon Jun 25 00:01:59 2012 +0300 @@ -154,7 +154,7 @@ /* original message's headers */ str_printfa(str, "--%s\r\nContent-Type: message/rfc822\r\n\r\n", boundary); - o_stream_send(output, str_data(str), str_len(str)); + o_stream_nsend(output, str_data(str), str_len(str)); if (mail_get_hdr_stream(mail, NULL, &input) == 0) { /* Note: If you add more headers, they need to be sorted. @@ -179,7 +179,7 @@ str_truncate(str, 0); str_printfa(str, "\r\n\r\n--%s--\r\n", boundary); - o_stream_send(output, str_data(str), str_len(str)); + o_stream_nsend(output, str_data(str), str_len(str)); return smtp_client_close(smtp_client); } @@ -209,7 +209,7 @@ N_ELEMENTS(hide_headers), null_header_filter_callback, NULL); - o_stream_send_istream(output, input); + (void)o_stream_send_istream(output, input); i_stream_unref(&input); return smtp_client_close(smtp_client); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-lda/smtp-client.c --- a/src/lib-lda/smtp-client.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-lda/smtp-client.c Mon Jun 25 00:01:59 2012 +0300 @@ -256,7 +256,7 @@ } } - if (o_stream_flush(smtp_client->output) < 0) { + if (o_stream_nfinish(smtp_client->output) < 0) { i_error("write(%s) failed: %m", smtp_client->temp_path); return -1; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-master/anvil-client.c --- a/src/lib-master/anvil-client.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-master/anvil-client.c Mon Jun 25 00:01:59 2012 +0300 @@ -140,8 +140,9 @@ client->fd = fd; client->input = i_stream_create_fd(fd, ANVIL_INBUF_SIZE, FALSE); client->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); client->io = io_add(fd, IO_READ, anvil_input, client); - o_stream_send_str(client->output, ANVIL_HANDSHAKE); + o_stream_nsend_str(client->output, ANVIL_HANDSHAKE); return 0; } @@ -185,7 +186,7 @@ iov[0].iov_len = strlen(cmd); iov[1].iov_base = "\n"; iov[1].iov_len = 1; - o_stream_sendv(client->output, iov, 2); + o_stream_nsendv(client->output, iov, 2); return 0; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-master/ipc-client.c --- a/src/lib-master/ipc-client.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-master/ipc-client.c Mon Jun 25 00:01:59 2012 +0300 @@ -92,6 +92,7 @@ client->io = io_add(client->fd, IO_READ, ipc_client_input, client); client->input = i_stream_create_fd(client->fd, (size_t)-1, FALSE); client->output = o_stream_create_fd(client->fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); return 0; } @@ -156,7 +157,7 @@ iov[0].iov_len = strlen(cmd); iov[1].iov_base = "\n"; iov[1].iov_len = 1; - o_stream_sendv(client->output, iov, N_ELEMENTS(iov)); + o_stream_nsendv(client->output, iov, N_ELEMENTS(iov)); ipc_cmd = array_append_space(&client->cmds); ipc_cmd->callback = callback; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-master/ipc-server.c --- a/src/lib-master/ipc-server.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-master/ipc-server.c Mon Jun 25 00:01:59 2012 +0300 @@ -111,7 +111,8 @@ server->io = io_add(server->fd, IO_READ, ipc_server_input, server); server->input = i_stream_create_fd(server->fd, (size_t)-1, FALSE); server->output = o_stream_create_fd(server->fd, (size_t)-1, FALSE); - o_stream_send_str(server->output, + o_stream_set_no_error_handling(server->output, TRUE); + o_stream_nsend_str(server->output, t_strdup_printf(IPC_SERVER_HANDSHAKE, server->name, my_pid)); o_stream_cork(server->output); } @@ -160,14 +161,14 @@ void ipc_cmd_send(struct ipc_cmd *cmd, const char *data) { - o_stream_send_str(cmd->server->output, - t_strdup_printf("%u\t:%s\n", cmd->tag, data)); + o_stream_nsend_str(cmd->server->output, + t_strdup_printf("%u\t:%s\n", cmd->tag, data)); } static void ipc_cmd_finish(struct ipc_cmd *cmd, const char *line) { - o_stream_send_str(cmd->server->output, - t_strdup_printf("%u\t%s\n", cmd->tag, line)); + o_stream_nsend_str(cmd->server->output, + t_strdup_printf("%u\t%s\n", cmd->tag, line)); o_stream_uncork(cmd->server->output); i_assert(cmd->server->ipc_cmd_refcount > 0); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-master/master-instance.c --- a/src/lib-master/master-instance.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-master/master-instance.c Mon Jun 25 00:01:59 2012 +0300 @@ -130,6 +130,7 @@ struct ostream *output; const struct master_instance *inst; string_t *str = t_str_new(128); + int ret = 0; output = o_stream_create_fd(fd, 0, FALSE); o_stream_cork(output); @@ -143,16 +144,14 @@ if (inst->config_path != NULL) str_tabescape_write(str, inst->config_path); str_append_c(str, '\n'); - (void)o_stream_send(output, str_data(str), str_len(str)); + o_stream_nsend(output, str_data(str), str_len(str)); } - o_stream_uncork(output); - (void)o_stream_flush(output); - if (output->last_failed_errno != 0) { - errno = output->last_failed_errno; + if (o_stream_nfinish(output) < 0) { i_error("write(%s) failed: %m", path); - return -1; + ret = -1; } - return 0; + o_stream_destroy(&output); + return ret; } static int master_instance_write_init(struct master_instance_list *list, diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-master/master-login-auth.c --- a/src/lib-master/master-login-auth.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-master/master-login-auth.c Mon Jun 25 00:01:59 2012 +0300 @@ -388,6 +388,7 @@ auth->fd = fd; auth->input = i_stream_create_fd(fd, AUTH_MAX_INBUF_SIZE, FALSE); auth->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(auth->output, TRUE); auth->io = io_add(fd, IO_READ, master_login_auth_input, auth); return 0; } @@ -436,7 +437,7 @@ req->client_pid, req->auth_id); binary_to_hex_append(str, req->cookie, sizeof(req->cookie)); str_append_c(str, '\n'); - o_stream_send(auth->output, str_data(str), str_len(str)); + o_stream_nsend(auth->output, str_data(str), str_len(str)); } void master_login_auth_request(struct master_login_auth *auth, @@ -456,7 +457,7 @@ context); return; } - o_stream_send_str(auth->output, + o_stream_nsend_str(auth->output, t_strdup_printf("VERSION\t%u\t%u\n", AUTH_MASTER_PROTOCOL_MAJOR_VERSION, AUTH_MASTER_PROTOCOL_MINOR_VERSION)); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-master/master-login.c --- a/src/lib-master/master-login.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-master/master-login.c Mon Jun 25 00:01:59 2012 +0300 @@ -359,7 +359,7 @@ reply.status = errormsg == NULL ? MASTER_AUTH_STATUS_OK : MASTER_AUTH_STATUS_INTERNAL_ERROR; reply.mail_pid = getpid(); - o_stream_send(conn->output, &reply, sizeof(reply)); + o_stream_nsend(conn->output, &reply, sizeof(reply)); if (errormsg != NULL || auth_args[0] == NULL) { if (auth_args != NULL) { @@ -447,6 +447,7 @@ conn->fd = fd; conn->io = io_add(conn->fd, IO_READ, master_login_conn_input, conn); conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); DLLIST_PREPEND(&login->conns, conn); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-storage/index/cydir/cydir-save.c --- a/src/lib-storage/index/cydir/cydir-save.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-storage/index/cydir/cydir-save.c Mon Jun 25 00:01:59 2012 +0300 @@ -141,7 +141,7 @@ if (o_stream_send_istream(_ctx->output, ctx->input) < 0) { if (!mail_storage_set_error_from_errno(storage)) { mail_storage_set_critical(storage, - "o_stream_send_istream(%s) failed: %m", + "write(%s) failed: %m", cydir_get_save_path(ctx, ctx->mail_count)); } ctx->failed = TRUE; @@ -162,9 +162,8 @@ struct stat st; int ret = 0; - if (o_stream_flush(ctx->ctx.output) < 0) { - mail_storage_set_critical(storage, - "o_stream_flush(%s) failed: %m", path); + if (o_stream_nfinish(ctx->ctx.output) < 0) { + mail_storage_set_critical(storage, "write(%s) failed: %m", path); ret = -1; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-storage/index/dbox-common/dbox-file-fix.c --- a/src/lib-storage/index/dbox-common/dbox-file-fix.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-file-fix.c Mon Jun 25 00:01:59 2012 +0300 @@ -79,7 +79,7 @@ static int stream_copy(struct dbox_file *file, struct ostream *output, - const char *path, uoff_t count) + const char *out_path, uoff_t count) { struct istream *input; off_t bytes; @@ -88,17 +88,22 @@ bytes = o_stream_send_istream(output, input); i_stream_unref(&input); - if (bytes < 0) { + if (input->stream_errno != 0) { mail_storage_set_critical(&file->storage->storage, - "o_stream_send_istream(%s, %s) failed: %m", - file->cur_path, path); + "read(%s) failed: %m", file->cur_path); return -1; } + if (o_stream_nfinish(output) < 0) { + mail_storage_set_critical(&file->storage->storage, + "write(%s) failed: %m", out_path); + return -1; + } + i_assert(bytes >= 0); if ((uoff_t)bytes != count) { mail_storage_set_critical(&file->storage->storage, "o_stream_send_istream(%s) copied only %" PRIuUOFF_T" of %"PRIuUOFF_T" bytes", - path, bytes, count); + out_path, bytes, count); return -1; } return 0; @@ -151,8 +156,8 @@ } if (*line == DBOX_METADATA_GUID) *have_guid_r = TRUE; - o_stream_send_str(output, line); - o_stream_send_str(output, "\n"); + o_stream_nsend_str(output, line); + o_stream_nsend_str(output, "\n"); } } @@ -238,7 +243,7 @@ /* write msg header */ if (write_header) { dbox_msg_header_fill(&msg_hdr, msg_size); - (void)o_stream_send(output, &msg_hdr, sizeof(msg_hdr)); + o_stream_nsend(output, &msg_hdr, sizeof(msg_hdr)); } /* write msg body */ i_assert(file->input->v_offset == body_offset); @@ -252,7 +257,7 @@ ret = message_get_body_size(body_input, &body, &has_nuls); i_stream_unref(&body_input); if (ret < 0) { - errno = output->stream_errno; + errno = body_input->stream_errno; mail_storage_set_critical(&file->storage->storage, "read(%s) failed: %m", file->cur_path); return -1; @@ -263,27 +268,28 @@ ret = dbox_file_metadata_skip_header(file); if (ret < 0) return -1; - o_stream_send_str(output, DBOX_MAGIC_POST); + o_stream_nsend_str(output, DBOX_MAGIC_POST); if (ret == 0) have_guid = FALSE; else dbox_file_copy_metadata(file, output, &have_guid); if (!have_guid) { guid_128_generate(guid_128); - o_stream_send_str(output, + o_stream_nsend_str(output, t_strdup_printf("%c%s\n", DBOX_METADATA_GUID, guid_128_to_string(guid_128))); } - o_stream_send_str(output, + o_stream_nsend_str(output, t_strdup_printf("%c%llx\n", DBOX_METADATA_VIRTUAL_SIZE, (unsigned long long)body.virtual_size)); - o_stream_send_str(output, "\n"); - if (output->stream_errno != 0) { - errno = output->stream_errno; - mail_storage_set_critical(&file->storage->storage, - "write(%s) failed: %m", temp_path); - return -1; - } + o_stream_nsend_str(output, "\n"); + if (output->stream_errno != 0) + break; + } + if (o_stream_nfinish(output) < 0) { + mail_storage_set_critical(&file->storage->storage, + "write(%s) failed: %m", temp_path); + ret = -1; } return ret; } @@ -307,7 +313,10 @@ return -1; output = o_stream_create_fd_file(fd, 0, FALSE); + o_stream_cork(output); ret = dbox_file_fix_write_stream(file, start_offset, temp_path, output); + if (ret < 0) + o_stream_ignore_last_errors(output); o_stream_unref(&output); if (close(fd) < 0) { mail_storage_set_critical(&file->storage->storage, diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-storage/index/dbox-common/dbox-file.c --- a/src/lib-storage/index/dbox-common/dbox-file.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-file.c Mon Jun 25 00:01:59 2012 +0300 @@ -519,8 +519,10 @@ if (ftruncate(file->fd, ctx->first_append_offset) < 0) dbox_file_set_syscall_error(file, "ftruncate()"); } - if (ctx->output != NULL) + if (ctx->output != NULL) { + o_stream_ignore_last_errors(ctx->output); o_stream_unref(&ctx->output); + } i_free(ctx); if (close_file) @@ -535,7 +537,7 @@ if (ctx->last_flush_offset == ctx->output->offset) return 0; - if (o_stream_flush(ctx->output) < 0) { + if (o_stream_nfinish(ctx->output) < 0) { dbox_file_set_syscall_error(ctx->file, "write()"); return -1; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-storage/index/dbox-common/dbox-save.c --- a/src/lib-storage/index/dbox-common/dbox-save.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-save.c Mon Jun 25 00:01:59 2012 +0300 @@ -55,9 +55,8 @@ o_stream_cork(ctx->dbox_output); if (o_stream_send(ctx->dbox_output, &dbox_msg_hdr, sizeof(dbox_msg_hdr)) < 0) { - mail_storage_set_critical(_storage, - "o_stream_send(%s) failed: %m", - ctx->cur_file->cur_path); + mail_storage_set_critical(_storage, "write(%s) failed: %m", + o_stream_get_name(ctx->dbox_output)); ctx->failed = TRUE; } _ctx->output = ctx->dbox_output; @@ -82,8 +81,8 @@ if (o_stream_send_istream(_ctx->output, ctx->input) < 0) { if (!mail_storage_set_error_from_errno(storage)) { mail_storage_set_critical(storage, - "o_stream_send_istream(%s) failed: %m", - ctx->cur_file->cur_path); + "write(%s) failed: %m", + o_stream_get_name(_ctx->output)); } ctx->failed = TRUE; return -1; @@ -128,7 +127,7 @@ memset(&metadata_hdr, 0, sizeof(metadata_hdr)); memcpy(metadata_hdr.magic_post, DBOX_MAGIC_POST, sizeof(metadata_hdr.magic_post)); - o_stream_send(output, &metadata_hdr, sizeof(metadata_hdr)); + o_stream_nsend(output, &metadata_hdr, sizeof(metadata_hdr)); str = t_str_new(256); if (output_msg_size != ctx->input->v_offset) { @@ -173,5 +172,5 @@ dbox_attachment_save_write_metadata(_ctx, str); str_append_c(str, '\n'); - o_stream_send(output, str_data(str), str_len(str)); + o_stream_nsend(output, str_data(str), str_len(str)); } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-storage/index/dbox-multi/mdbox-purge.c --- a/src/lib-storage/index/dbox-multi/mdbox-purge.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-storage/index/dbox-multi/mdbox-purge.c Mon Jun 25 00:01:59 2012 +0300 @@ -105,7 +105,7 @@ if ((ret = mdbox_file_read_metadata_hdr(file, &meta_hdr)) <= 0) return ret; - o_stream_send(output, &meta_hdr, sizeof(meta_hdr)); + o_stream_nsend(output, &meta_hdr, sizeof(meta_hdr)); buf_size = i_stream_get_max_buffer_size(file->input); /* use unlimited line length for metadata */ i_stream_set_max_buffer_size(file->input, (size_t)-1); @@ -114,8 +114,8 @@ /* end of metadata */ break; } - o_stream_send_str(output, line); - o_stream_send(output, "\n", 1); + o_stream_nsend_str(output, line); + o_stream_nsend(output, "\n", 1); } i_stream_set_max_buffer_size(file->input, buf_size); @@ -123,7 +123,7 @@ dbox_file_set_corrupted(file, "missing end-of-metadata line"); return 0; } - o_stream_send(output, "\n", 1); + o_stream_nsend(output, "\n", 1); return 1; } @@ -217,8 +217,7 @@ "read(%s) failed: %m", file->cur_path); return -1; } - if (output->stream_errno != 0) { - errno = output->stream_errno; + if (o_stream_nfinish(output) < 0) { mail_storage_set_critical(&file->storage->storage, "write(%s) failed: %m", out_file_append->file->cur_path); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-storage/index/dbox-single/sdbox-file.c --- a/src/lib-storage/index/dbox-single/sdbox-file.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-storage/index/dbox-single/sdbox-file.c Mon Jun 25 00:01:59 2012 +0300 @@ -310,10 +310,7 @@ output = o_stream_create_fd_file(out_fd, 0, FALSE); i_stream_seek(file->input, 0); while ((ret = o_stream_send_istream(output, file->input)) > 0) ; - if (ret == 0) - ret = o_stream_flush(output); - if (output->stream_errno != 0) { - errno = output->stream_errno; + if (o_stream_nfinish(output) < 0) { mail_storage_set_critical(storage, "write(%s) failed: %m", temp_path); ret = -1; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-storage/index/imapc/imapc-save.c --- a/src/lib-storage/index/imapc/imapc-save.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-storage/index/imapc/imapc-save.c Mon Jun 25 00:01:59 2012 +0300 @@ -241,11 +241,10 @@ ctx->finished = TRUE; if (!ctx->failed) { - if (o_stream_flush(_ctx->output) < 0) { + if (o_stream_nfinish(_ctx->output) < 0) { if (!mail_storage_set_error_from_errno(storage)) { mail_storage_set_critical(storage, - "o_stream_flush(%s) failed: %m", - ctx->temp_path); + "write(%s) failed: %m", ctx->temp_path); } ctx->failed = TRUE; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-storage/index/index-attachment.c --- a/src/lib-storage/index/index-attachment.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-storage/index/index-attachment.c Mon Jun 25 00:01:59 2012 +0300 @@ -133,14 +133,14 @@ else if (strcasecmp(hdr->name, "Content-Disposition") == 0) parse_content_disposition(ctx, hdr); - o_stream_send(ctx->output, hdr->name, hdr->name_len); - o_stream_send(ctx->output, hdr->middle, hdr->middle_len); - o_stream_send(ctx->output, hdr->full_value, hdr->full_value_len); + o_stream_nsend(ctx->output, hdr->name, hdr->name_len); + o_stream_nsend(ctx->output, hdr->middle, hdr->middle_len); + o_stream_nsend(ctx->output, hdr->full_value, hdr->full_value_len); if (!hdr->no_newline) { if (hdr->crlf_newline) - o_stream_send(ctx->output, "\r\n", 2); + o_stream_nsend(ctx->output, "\r\n", 2); else - o_stream_send(ctx->output, "\n", 1); + o_stream_nsend(ctx->output, "\n", 1); } } @@ -221,10 +221,9 @@ static int save_check_write_error(struct mail_storage *storage, struct ostream *output) { - if (output->last_failed_errno == 0) + if (o_stream_nfinish(output) == 0) return 0; - errno = output->last_failed_errno; if (!mail_storage_set_error_from_errno(storage)) { mail_storage_set_critical(storage, "write(%s) failed: %m", o_stream_get_name(output)); @@ -282,7 +281,7 @@ break; } i_stream_skip(base64_input, size); - o_stream_send(output, buf->data, buf->used); + o_stream_nsend(output, buf->data, buf->used); hash_format_loop(hash, buf->data, buf->used); } if (ret != -1) { @@ -293,7 +292,6 @@ failed = TRUE; } - (void)o_stream_flush(output); if (save_check_write_error(storage, output) < 0) failed = TRUE; @@ -335,7 +333,7 @@ part->temp_fd = outfd; if (extra_buf != NULL) { - o_stream_send(ctx->output, extra_buf->data, extra_buf->used); + o_stream_nsend(ctx->output, extra_buf->data, extra_buf->used); buffer_free(&extra_buf); } hash_format_deinit_free(&part->part_hash); @@ -359,10 +357,8 @@ enum fs_open_flags flags = FS_OPEN_FLAG_MKDIR; int ret = 0; - if (o_stream_flush(part->output) < 0) { - save_check_write_error(storage, part->output); + if (save_check_write_error(storage, part->output) < 0) return -1; - } if (!part->base64_failed) { if (part->base64_state == BASE64_STATE_0 && @@ -410,7 +406,7 @@ input = i_stream_create_fd(part->temp_fd, IO_BLOCK_SIZE, FALSE); output = fs_write_stream(file); while (i_stream_read_data(input, &data, &size, 0) > 0) { - o_stream_send(output, data, size); + o_stream_nsend(output, data, size); i_stream_skip(input, size); } @@ -557,7 +553,7 @@ switch (part->state) { case MAIL_ATTACHMENT_STATE_NO: - o_stream_send(ctx->output, block->data, block->size); + o_stream_nsend(ctx->output, block->data, block->size); break; case MAIL_ATTACHMENT_STATE_MAYBE: if (part->part_buf == NULL) { @@ -576,9 +572,9 @@ if (index_attachment_save_temp_open(ctx) < 0) { /* failed, fallback to just saving it inline */ part->state = MAIL_ATTACHMENT_STATE_NO; - o_stream_send(ctx->output, part_buf->data, - part_buf->used); - o_stream_send(ctx->output, block->data, block->size); + o_stream_nsend(ctx->output, part_buf->data, + part_buf->used); + o_stream_nsend(ctx->output, block->data, block->size); break; } part->state = MAIL_ATTACHMENT_STATE_YES; @@ -586,14 +582,14 @@ part_buf->used); hash_format_loop(part->part_hash, part_buf->data, part_buf->used); - o_stream_send(part->output, part_buf->data, part_buf->used); + o_stream_nsend(part->output, part_buf->data, part_buf->used); buffer_set_used_size(part_buf, 0); /* fall through */ case MAIL_ATTACHMENT_STATE_YES: index_attachment_try_base64_decode(part, block->data, block->size); hash_format_loop(part->part_hash, block->data, block->size); - o_stream_send(part->output, block->data, block->size); + o_stream_nsend(part->output, block->data, block->size); break; } } @@ -626,8 +622,8 @@ case MAIL_ATTACHMENT_STATE_MAYBE: /* body part wasn't large enough. write to main file. */ if (part->part_buf != NULL) { - o_stream_send(ctx->output, part->part_buf->data, - part->part_buf->used); + o_stream_nsend(ctx->output, part->part_buf->data, + part->part_buf->used); } break; case MAIL_ATTACHMENT_STATE_YES: diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-storage/index/maildir/maildir-save.c --- a/src/lib-storage/index/maildir/maildir-save.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-storage/index/maildir/maildir-save.c Mon Jun 25 00:01:59 2012 +0300 @@ -529,10 +529,10 @@ } path = t_strconcat(ctx->tmpdir, "/", ctx->file_last->tmp_name, NULL); - if (!ctx->failed && o_stream_flush(_ctx->output) < 0) { + if (!ctx->failed && o_stream_nfinish(_ctx->output) < 0) { if (!mail_storage_set_error_from_errno(storage)) { mail_storage_set_critical(storage, - "o_stream_flush(%s) failed: %m", path); + "write(%s) failed: %m", path); } ctx->failed = TRUE; } @@ -562,7 +562,7 @@ &ctx->file_last->vsize) < 0) ctx->file_last->vsize = (uoff_t)-1; - output_errno = _ctx->output->stream_errno; + output_errno = _ctx->output->last_failed_errno; o_stream_destroy(&_ctx->output); if (storage->set->parsed_fsync_mode != FSYNC_MODE_NEVER && diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-storage/index/maildir/maildir-uidlist.c --- a/src/lib-storage/index/maildir/maildir-uidlist.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-storage/index/maildir/maildir-uidlist.c Mon Jun 25 00:01:59 2012 +0300 @@ -1241,7 +1241,6 @@ const unsigned char *p; const char *strp; unsigned int len; - int ret; i_assert(fd != -1); @@ -1271,7 +1270,7 @@ str_append_str(str, uidlist->hdr_extensions); } str_append_c(str, '\n'); - o_stream_send(output, str_data(str), str_len(str)); + o_stream_nsend(output, str_data(str), str_len(str)); } iter = maildir_uidlist_iter_init(uidlist); @@ -1298,22 +1297,19 @@ else str_append_n(str, rec->filename, strp - rec->filename); str_append_c(str, '\n'); - o_stream_send(output, str_data(str), str_len(str)); + o_stream_nsend(output, str_data(str), str_len(str)); } maildir_uidlist_iter_deinit(&iter); - o_stream_flush(output); - ret = output->stream_errno == 0 ? 0 : -1; + if (o_stream_nfinish(output) < 0) { + mail_storage_set_critical(storage, "write(%s) failed: %m", path); + o_stream_unref(&output); + return -1; + } *file_size_r = output->offset; o_stream_unref(&output); - if (ret < 0) { - mail_storage_set_critical(storage, - "o_stream_send(%s) failed: %m", path); - return -1; - } - if (storage->set->parsed_fsync_mode != FSYNC_MODE_NEVER) { if (fdatasync(fd) < 0) { mail_storage_set_critical(storage, diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-storage/index/mbox/mbox-save.c --- a/src/lib-storage/index/mbox/mbox-save.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-storage/index/mbox/mbox-save.c Mon Jun 25 00:01:59 2012 +0300 @@ -660,7 +660,7 @@ if (ctx->output != NULL) { /* make sure everything is written */ - if (o_stream_flush(ctx->output) < 0) + if (o_stream_nfinish(ctx->output) < 0) write_error(ctx); } @@ -684,7 +684,7 @@ if (ctx->failed && ctx->mail_offset != (uoff_t)-1) { /* saving this mail failed - truncate back to beginning of it */ - (void)o_stream_flush(ctx->output); + (void)o_stream_nfinish(ctx->output); if (ftruncate(ctx->mbox->mbox_fd, (off_t)ctx->mail_offset) < 0) mbox_set_syscall_error(ctx->mbox, "ftruncate()"); o_stream_seek(ctx->output, ctx->mail_offset); @@ -722,7 +722,7 @@ /* failed, truncate file back to original size. output stream needs to be flushed before truncating so unref() won't write anything. */ if (ctx->output != NULL) - o_stream_flush(ctx->output); + (void)o_stream_flush(ctx->output); if (ftruncate(ctx->mbox->mbox_fd, (off_t)ctx->append_offset) < 0) mbox_set_syscall_error(ctx->mbox, "ftruncate()"); @@ -777,7 +777,8 @@ if (ctx->output != NULL) { /* flush the final LF */ - o_stream_flush(ctx->output); + if (o_stream_nfinish(ctx->output) < 0) + write_error(ctx); } if (mbox->mbox_fd != -1 && !mbox->mbox_writeonly && mbox->storage->storage.set->parsed_fsync_mode != FSYNC_MODE_NEVER) { diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-storage/index/pop3c/pop3c-client.c --- a/src/lib-storage/index/pop3c/pop3c-client.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-storage/index/pop3c/pop3c-client.c Mon Jun 25 00:01:59 2012 +0300 @@ -256,12 +256,12 @@ } if (set->master_user == NULL) { - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, t_strdup_printf("USER %s\r\n", set->username)); client->state = POP3C_CLIENT_STATE_USER; } else { client->state = POP3C_CLIENT_STATE_AUTH; - o_stream_send_str(client->output, "AUTH PLAIN\r\n"); + o_stream_nsend_str(client->output, "AUTH PLAIN\r\n"); } } @@ -320,7 +320,7 @@ client->set.host, line); return -1; } - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, t_strdup_printf("PASS %s\r\n", client->set.password)); client->state = POP3C_CLIENT_STATE_PASS; break; @@ -330,7 +330,7 @@ client->set.host, line); return -1; } - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, pop3c_client_get_sasl_plain_request(client)); client->state = POP3C_CLIENT_STATE_PASS; break; @@ -349,7 +349,7 @@ if (!success) return -1; - o_stream_send_str(client->output, "CAPA\r\n"); + o_stream_nsend_str(client->output, "CAPA\r\n"); client->state = POP3C_CLIENT_STATE_CAPA; break; case POP3C_CLIENT_STATE_CAPA: @@ -529,6 +529,7 @@ i_stream_create_fd(client->fd, POP3C_MAX_INBUF_SIZE, FALSE); client->output = client->raw_output = o_stream_create_fd(client->fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); if (*client->set.rawlog_dir != '\0' && client->set.ssl_mode != POP3C_CLIENT_SSL_MODE_IMMEDIATE && @@ -662,7 +663,7 @@ if (pop3c_client_flush_asyncs(client, reply_r) < 0) return -1; - o_stream_send_str(client->output, cmd); + o_stream_nsend_str(client->output, cmd); if (pop3c_client_read_line(client, &line, reply_r) < 0) return -1; if (strncasecmp(line, "+OK", 3) == 0) { @@ -693,7 +694,7 @@ if (pop3c_client_flush_asyncs(client, &error) < 0) return; } - o_stream_send_str(client->output, cmd); + o_stream_nsend_str(client->output, cmd); client->async_commands++; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib-storage/list/subscription-file.c --- a/src/lib-storage/list/subscription-file.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib-storage/list/subscription-file.c Mon Jun 25 00:01:59 2012 +0300 @@ -152,8 +152,8 @@ } } - (void)o_stream_send_str(output, line); - (void)o_stream_send(output, "\n", 1); + o_stream_nsend_str(output, line); + o_stream_nsend(output, "\n", 1); } i_stream_destroy(&input); } @@ -161,12 +161,12 @@ if (!failed && set && !found) { /* append subscription */ line = t_strconcat(name, "\n", NULL); - (void)o_stream_send_str(output, line); + o_stream_nsend_str(output, line); changed = TRUE; } if (changed && !failed) { - if (o_stream_flush(output) < 0) { + if (o_stream_nfinish(output) < 0) { subswrite_set_syscall_error(list, "write()", path); failed = TRUE; } else if (mail_set->parsed_fsync_mode != FSYNC_MODE_NEVER) { diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib/ostream-file.c --- a/src/lib/ostream-file.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib/ostream-file.c Mon Jun 25 00:01:59 2012 +0300 @@ -72,7 +72,7 @@ struct file_ostream *fstream = (struct file_ostream *)stream; /* flush output before really closing it */ - o_stream_flush(&fstream->ostream.ostream); + (void)o_stream_flush(&fstream->ostream.ostream); stream_closed(fstream); } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib/ostream-private.h --- a/src/lib/ostream-private.h Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib/ostream-private.h Mon Jun 25 00:01:59 2012 +0300 @@ -36,6 +36,8 @@ void *context; unsigned int corked:1; + unsigned int last_errors_not_checked:1; + unsigned int error_handling_disabled:1; }; struct ostream * diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib/ostream-rawlog.c --- a/src/lib/ostream-rawlog.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib/ostream-rawlog.c Mon Jun 25 00:01:59 2012 +0300 @@ -14,7 +14,7 @@ { struct rawlog_ostream *rstream = (struct rawlog_ostream *)stream; - o_stream_flush(rstream->ostream.parent); + (void)o_stream_flush(rstream->ostream.parent); iostream_rawlog_close(&rstream->riostream); } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib/ostream.c --- a/src/lib/ostream.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib/ostream.c Mon Jun 25 00:01:59 2012 +0300 @@ -31,10 +31,19 @@ io_stream_ref(&stream->real_stream->iostream); } -void o_stream_unref(struct ostream **stream) +void o_stream_unref(struct ostream **_stream) { - io_stream_unref(&(*stream)->real_stream->iostream); - *stream = NULL; + struct ostream *stream = *_stream; + + if (!stream->real_stream->last_errors_not_checked && + !stream->real_stream->error_handling_disabled && + stream->real_stream->iostream.refcount == 1) { + i_panic("output stream %s is missing error handling", + o_stream_get_name(stream)); + } + + io_stream_unref(&stream->real_stream->iostream); + *_stream = NULL; } void o_stream_close(struct ostream *stream) @@ -196,6 +205,57 @@ return o_stream_send(stream, str, strlen(str)); } +void o_stream_nsend(struct ostream *stream, const void *data, size_t size) +{ + struct const_iovec iov; + + memset(&iov, 0, sizeof(iov)); + iov.iov_base = data; + iov.iov_len = size; + + (void)o_stream_nsendv(stream, &iov, 1); +} + +void o_stream_nsendv(struct ostream *stream, const struct const_iovec *iov, + unsigned int iov_count) +{ + if (unlikely(stream->closed)) + return; + (void)o_stream_sendv(stream, iov, iov_count); + stream->real_stream->last_errors_not_checked = TRUE; +} + +void o_stream_nsend_str(struct ostream *stream, const char *str) +{ + o_stream_nsend(stream, str, strlen(str)); +} + +void o_stream_nflush(struct ostream *stream) +{ + if (unlikely(stream->closed)) + return; + (void)o_stream_flush(stream); + stream->real_stream->last_errors_not_checked = TRUE; +} + +int o_stream_nfinish(struct ostream *stream) +{ + o_stream_nflush(stream); + stream->real_stream->last_errors_not_checked = FALSE; + errno = stream->last_failed_errno; + return stream->last_failed_errno != 0 ? -1 : 0; +} + +void o_stream_ignore_last_errors(struct ostream *stream) +{ + stream->real_stream->last_errors_not_checked = FALSE; +} + +void o_stream_set_no_error_handling(struct ostream *stream, bool set) +{ + stream->real_stream->error_handling_disabled = set; +} + off_t o_stream_send_istream(struct ostream *outstream, struct istream *instream) { @@ -406,6 +466,8 @@ _stream->callback = parent->real_stream->callback; _stream->context = parent->real_stream->context; _stream->max_buffer_size = parent->real_stream->max_buffer_size; + _stream->error_handling_disabled = + parent->real_stream->error_handling_disabled; } if (_stream->iostream.close == NULL) diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib/ostream.h --- a/src/lib/ostream.h Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib/ostream.h Mon Jun 25 00:01:59 2012 +0300 @@ -88,6 +88,26 @@ ssize_t o_stream_sendv(struct ostream *stream, const struct const_iovec *iov, unsigned int iov_count); ssize_t o_stream_send_str(struct ostream *stream, const char *str); +/* Send with delayed error handling. o_stream_has_errors() or + o_stream_ignore_errors() must be called after these functions before the + stream is destroyed. */ +void o_stream_nsend(struct ostream *stream, const void *data, size_t size); +void o_stream_nsendv(struct ostream *stream, const struct const_iovec *iov, + unsigned int iov_count); +void o_stream_nsend_str(struct ostream *stream, const char *str); +void o_stream_nflush(struct ostream *stream); +/* Flushes the stream and returns -1 if stream->last_failed_errno is + non-zero. Marks the stream's error handling as completed. errno is also set + to last_failed_errno. */ +int o_stream_nfinish(struct ostream *stream); +/* Marks the stream's error handling as completed to avoid i_panic() on + destroy. */ +void o_stream_ignore_last_errors(struct ostream *stream); +/* If error handling is disabled, the i_panic() on destroy is never called. + This function can be called immediately after the stream is created. + When creating wrapper streams, they copy this behavior from the parent + stream. */ +void o_stream_set_no_error_handling(struct ostream *stream, bool set); /* Send data from input stream. Returns number of bytes sent, or -1 if error. Note that this function may block if either instream or outstream is blocking. diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lib/test-ostream-file.c --- a/src/lib/test-ostream-file.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lib/test-ostream-file.c Mon Jun 25 00:01:59 2012 +0300 @@ -32,7 +32,7 @@ size = (rand() % MAX_BUFSIZE) + 1; random_fill_weak(randbuf, size); memcpy(buf, randbuf, size); - o_stream_send(output, buf, size); + (void)o_stream_send(output, buf, size); for (i = 0; i < 10; i++) { offset = rand() % (MAX_BUFSIZE*3); @@ -41,10 +41,10 @@ memcpy(buf + offset, randbuf, size); o_stream_pwrite(output, randbuf, size, offset); if (rand() % 10 == 0) - o_stream_flush(output); + (void)o_stream_flush(output); } - o_stream_flush(output); + (void)o_stream_flush(output); o_stream_uncork(output); ret = pread(fd, buf2, sizeof(buf2), 0); if (ret < 0) diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lmtp/client.c --- a/src/lmtp/client.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lmtp/client.c Mon Jun 25 00:01:59 2012 +0300 @@ -217,6 +217,7 @@ client->input = i_stream_create_fd(fd_in, CLIENT_MAX_INPUT_SIZE, FALSE); client->output = o_stream_create_fd(fd_out, (size_t)-1, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); client_io_reset(client); client->state_pool = pool_alloconly_create("client state", 4096); @@ -340,7 +341,7 @@ str = t_str_new(256); str_vprintfa(str, fmt, args); str_append(str, "\r\n"); - o_stream_send(client->output, str_data(str), str_len(str)); + o_stream_nsend(client->output, str_data(str), str_len(str)); } T_END; va_end(args); } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/lmtp/lmtp-proxy.c --- a/src/lmtp/lmtp-proxy.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/lmtp/lmtp-proxy.c Mon Jun 25 00:01:59 2012 +0300 @@ -164,8 +164,8 @@ for (i = proxy->next_data_reply_idx; i < count; i++) { if (!(rcpt[i]->rcpt_to_failed || rcpt[i]->data_reply_received)) break; - o_stream_send_str(proxy->client_output, - t_strconcat(rcpt[i]->reply, "\r\n", NULL)); + o_stream_nsend_str(proxy->client_output, + t_strconcat(rcpt[i]->reply, "\r\n", NULL)); } o_stream_uncork(proxy->client_output); proxy->next_data_reply_idx = i; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/login-common/client-common-auth.c --- a/src/login-common/client-common-auth.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/login-common/client-common-auth.c Mon Jun 25 00:01:59 2012 +0300 @@ -486,7 +486,7 @@ iov[2].iov_base = "\r\n"; iov[2].iov_len = 2; - (void)o_stream_sendv(client->output, iov, 3); + o_stream_nsendv(client->output, iov, 3); } static void diff -r 3ffdb4bf36d3 -r ca37d1577291 src/login-common/client-common.c --- a/src/login-common/client-common.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/login-common/client-common.c Mon Jun 25 00:01:59 2012 +0300 @@ -66,6 +66,7 @@ i_stream_create_fd(client->fd, LOGIN_MAX_INBUF_SIZE, FALSE); client->output = o_stream_create_fd(client->fd, LOGIN_MAX_OUTBUF_SIZE, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); if (login_rawlog_dir != NULL) { if (iostream_rawlog_create(login_rawlog_dir, &client->input, diff -r 3ffdb4bf36d3 -r ca37d1577291 src/login-common/login-proxy.c --- a/src/login-common/login-proxy.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/login-common/login-proxy.c Mon Jun 25 00:01:59 2012 +0300 @@ -175,6 +175,7 @@ FALSE); proxy->server_output = o_stream_create_fd(proxy->server_fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(proxy->server_output, TRUE); proxy->server_io = io_add(proxy->server_fd, IO_READ, proxy_prelogin_input, proxy); @@ -456,7 +457,7 @@ /* send all pending client input to proxy and get rid of the stream */ data = i_stream_get_data(client->input, &size); if (size != 0) - (void)o_stream_send(proxy->server_output, data, size); + o_stream_nsend(proxy->server_output, data, size); /* from now on, just do dummy proxying */ io_remove(&proxy->server_io); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/plugins/acl/acl-backend-vfile-acllist.c --- a/src/plugins/acl/acl-backend-vfile-acllist.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/plugins/acl/acl-backend-vfile-acllist.c Mon Jun 25 00:01:59 2012 +0300 @@ -187,7 +187,7 @@ const char *line; line = t_strdup_printf("%s %s\n", dec2str(acllist.mtime), name); - o_stream_send_str(output, line); + o_stream_nsend_str(output, line); } T_END; } acl_object_deinit(&aclobj); @@ -246,6 +246,7 @@ return -1; } output = o_stream_create_fd_file(fd, 0, FALSE); + o_stream_cork(output); ret = 0; acllist_clear(backend, 0); @@ -261,7 +262,7 @@ } } - if (output->stream_errno != 0) { + if (o_stream_nfinish(output) < 0) { i_error("write(%s) failed: %m", str_c(path)); ret = -1; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/plugins/acl/acl-backend-vfile.c --- a/src/plugins/acl/acl-backend-vfile.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/plugins/acl/acl-backend-vfile.c Mon Jun 25 00:01:59 2012 +0300 @@ -1072,17 +1072,17 @@ for (i = 0; i < count && !rights[i].global; i++) { if (rights[i].rights != NULL) { vfile_write_right(str, &rights[i], FALSE); - o_stream_send(output, str_data(str), str_len(str)); + o_stream_nsend(output, str_data(str), str_len(str)); str_truncate(str, 0); } if (rights[i].neg_rights != NULL) { vfile_write_right(str, &rights[i], TRUE); - o_stream_send(output, str_data(str), str_len(str)); + o_stream_nsend(output, str_data(str), str_len(str)); str_truncate(str, 0); } } str_free(&str); - if (o_stream_flush(output) < 0) { + if (o_stream_nfinish(output) < 0) { i_error("write(%s) failed: %m", path); ret = -1; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/plugins/fts-squat/squat-trie.c --- a/src/plugins/fts-squat/squat-trie.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/plugins/fts-squat/squat-trie.c Mon Jun 25 00:01:59 2012 +0300 @@ -590,8 +590,8 @@ base_offset = ctx->output->offset; child_count = node->child_count; - o_stream_send(ctx->output, &child_count, 1); - o_stream_send(ctx->output, chars, child_count); + o_stream_nsend(ctx->output, &child_count, 1); + o_stream_nsend(ctx->output, chars, child_count); for (i = 0; i < child_count; i++) { bufp = buf; @@ -618,17 +618,17 @@ if (children[i].leaf_string_length == 0) { /* 4a) unused uids */ squat_pack_num(&bufp, children[i].unused_uids << 1); - o_stream_send(ctx->output, buf, bufp - buf); + o_stream_nsend(ctx->output, buf, bufp - buf); } else { i_assert(node_offsets[i] == 0); /* 4b) unused uids + flag */ squat_pack_num(&bufp, (children[i].unused_uids << 1) | 1); /* 5) leaf string length */ squat_pack_num(&bufp, children[i].leaf_string_length - 1); - o_stream_send(ctx->output, buf, bufp - buf); - o_stream_send(ctx->output, - NODE_LEAF_STRING(&children[i]), - children[i].leaf_string_length); + o_stream_nsend(ctx->output, buf, bufp - buf); + o_stream_nsend(ctx->output, + NODE_LEAF_STRING(&children[i]), + children[i].leaf_string_length); } } } @@ -1642,7 +1642,7 @@ output = o_stream_create_fd(fd, 0, FALSE); o_stream_cork(output); - o_stream_send(output, &trie->hdr, sizeof(trie->hdr)); + o_stream_nsend(output, &trie->hdr, sizeof(trie->hdr)); } else { /* we need to lock only while header is being written */ path = trie->path; @@ -1660,7 +1660,7 @@ if (trie->hdr.used_file_size != 0) o_stream_seek(output, trie->hdr.used_file_size); else - o_stream_send(output, &trie->hdr, sizeof(trie->hdr)); + o_stream_nsend(output, &trie->hdr, sizeof(trie->hdr)); } ctx->output = output; @@ -1669,7 +1669,7 @@ /* write 1 byte guard at the end of file, so that we can verify broken squat_unpack_num() input by checking if data==end */ - o_stream_send(output, "", 1); + o_stream_nsend(output, "", 1); if (trie->corrupted) ret = -1; @@ -1678,10 +1678,9 @@ if (ret == 0) { trie->hdr.used_file_size = output->offset; o_stream_seek(output, 0); - o_stream_send(output, &trie->hdr, sizeof(trie->hdr)); + o_stream_nsend(output, &trie->hdr, sizeof(trie->hdr)); } - if (output->last_failed_errno != 0) { - errno = output->last_failed_errno; + if (o_stream_nfinish(output) < 0) { i_error("write() to %s failed: %m", path); ret = -1; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/plugins/fts-squat/squat-uidlist.c --- a/src/plugins/fts-squat/squat-uidlist.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/plugins/fts-squat/squat-uidlist.c Mon Jun 25 00:01:59 2012 +0300 @@ -221,10 +221,10 @@ if (write_size) { sizebufp = sizebuf; squat_pack_num(&sizebufp, size_value); - o_stream_send(output, sizebuf, sizebufp - sizebuf); + o_stream_nsend(output, sizebuf, sizebufp - sizebuf); } - o_stream_send(output, listbuf, listbufp - listbuf); - o_stream_send(output, uidbuf, uid_list_len); + o_stream_nsend(output, listbuf, listbufp - listbuf); + o_stream_nsend(output, uidbuf, uid_list_len); if (!datastack) i_free(uidbuf); @@ -251,7 +251,7 @@ if (list->uid_count == 1) { bufp = buf; squat_pack_num(&bufp, offset); - o_stream_send(output, buf, bufp - buf); + o_stream_nsend(output, buf, bufp - buf); *size_r = (bufp - buf) << 2 | packed_flags; return 0; } @@ -716,7 +716,7 @@ struct squat_uidlist_file_header hdr; memset(&hdr, 0, sizeof(hdr)); - o_stream_send(ctx->output, &hdr, sizeof(hdr)); + o_stream_nsend(ctx->output, &hdr, sizeof(hdr)); } o_stream_cork(ctx->output); i_array_init(&ctx->lists, 10240); @@ -756,7 +756,7 @@ if (align != 0) { static char null[sizeof(uint32_t)-1] = { 0, }; - o_stream_send(output, null, sizeof(uint32_t) - align); + o_stream_nsend(output, null, sizeof(uint32_t) - align); } block_list_offset = output->offset; @@ -764,18 +764,18 @@ old_block_count = write_old_blocks ? uidlist->cur_block_count : 0; block_offset_count = new_block_count + old_block_count; - o_stream_send(output, &block_offset_count, sizeof(block_offset_count)); + o_stream_nsend(output, &block_offset_count, sizeof(block_offset_count)); /* write end indexes */ - o_stream_send(output, uidlist->cur_block_end_indexes, - old_block_count * sizeof(uint32_t)); - o_stream_send(output, array_idx(block_end_indexes, 0), - new_block_count * sizeof(uint32_t)); + o_stream_nsend(output, uidlist->cur_block_end_indexes, + old_block_count * sizeof(uint32_t)); + o_stream_nsend(output, array_idx(block_end_indexes, 0), + new_block_count * sizeof(uint32_t)); /* write offsets */ - o_stream_send(output, uidlist->cur_block_offsets, - old_block_count * sizeof(uint32_t)); - o_stream_send(output, array_idx(block_offsets, 0), - new_block_count * sizeof(uint32_t)); - o_stream_flush(output); + o_stream_nsend(output, uidlist->cur_block_offsets, + old_block_count * sizeof(uint32_t)); + o_stream_nsend(output, array_idx(block_offsets, 0), + new_block_count * sizeof(uint32_t)); + (void)o_stream_flush(output); /* update header - it's written later when trie is locked */ ctx->build_hdr.block_list_offset = block_list_offset; @@ -820,13 +820,13 @@ /* write the full size of the uidlists */ bufp = buf; squat_pack_num(&bufp, block_offset - start_offset); - o_stream_send(ctx->output, buf, bufp - buf); + o_stream_nsend(ctx->output, buf, bufp - buf); /* write the sizes/flags */ for (j = 0; j < max; j++) { bufp = buf; squat_pack_num(&bufp, list_sizes[j]); - o_stream_send(ctx->output, buf, bufp - buf); + o_stream_nsend(ctx->output, buf, bufp - buf); } } @@ -856,14 +856,12 @@ if (!ctx->output->closed) { o_stream_seek(ctx->output, 0); - o_stream_send(ctx->output, - &ctx->build_hdr, sizeof(ctx->build_hdr)); + o_stream_nsend(ctx->output, + &ctx->build_hdr, sizeof(ctx->build_hdr)); o_stream_seek(ctx->output, ctx->build_hdr.used_file_size); - o_stream_flush(ctx->output); } - if (ctx->output->last_failed_errno != 0) { - errno = ctx->output->last_failed_errno; + if (o_stream_nfinish(ctx->output) < 0) { i_error("write() to %s failed: %m", ctx->uidlist->path); return -1; } @@ -891,6 +889,7 @@ array_free(&ctx->block_offsets); array_free(&ctx->block_end_indexes); array_free(&ctx->lists); + o_stream_ignore_last_errors(ctx->output); o_stream_unref(&ctx->output); i_free(ctx); } @@ -933,7 +932,7 @@ o_stream_cork(ctx->output); memset(&hdr, 0, sizeof(hdr)); - o_stream_send(ctx->output, &hdr, sizeof(hdr)); + o_stream_nsend(ctx->output, &hdr, sizeof(hdr)); ctx->cur_block_start_offset = ctx->output->offset; i_array_init(&ctx->new_block_offsets, @@ -962,13 +961,13 @@ ended to current offset. write the size of this area. */ bufp = buf; squat_pack_num(&bufp, block_offset - ctx->cur_block_start_offset); - o_stream_send(ctx->output, buf, bufp - buf); + o_stream_nsend(ctx->output, buf, bufp - buf); /* write the sizes/flags */ for (i = 0; i < ctx->list_idx; i++) { bufp = buf; squat_pack_num(&bufp, ctx->list_sizes[i]); - o_stream_send(ctx->output, buf, bufp - buf); + o_stream_nsend(ctx->output, buf, bufp - buf); } ctx->cur_block_start_offset = ctx->output->offset; } @@ -1058,16 +1057,14 @@ &ctx->new_block_end_indexes, FALSE); o_stream_seek(ctx->output, 0); - o_stream_send(ctx->output, &ctx->build_ctx->build_hdr, - sizeof(ctx->build_ctx->build_hdr)); + o_stream_nsend(ctx->output, &ctx->build_ctx->build_hdr, + sizeof(ctx->build_ctx->build_hdr)); o_stream_seek(ctx->output, ctx->build_ctx->build_hdr.used_file_size); - o_stream_flush(ctx->output); if (ctx->uidlist->corrupted) ret = -1; - else if (ctx->output->last_failed_errno != 0) { - errno = ctx->output->last_failed_errno; + else if (o_stream_nfinish(ctx->output) < 0) { i_error("write() to %s failed: %m", temp_path); ret = -1; } else if (rename(temp_path, ctx->uidlist->path) < 0) { @@ -1082,6 +1079,7 @@ let it be used for something more useful. */ squat_uidlist_free_from_memory(ctx->uidlist); + o_stream_ignore_last_errors(ctx->output); o_stream_unref(&ctx->output); if (close(ctx->fd) < 0) i_error("close(%s) failed: %m", temp_path); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/plugins/imap-quota/imap-quota-plugin.c --- a/src/plugins/imap-quota/imap-quota-plugin.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/plugins/imap-quota/imap-quota-plugin.c Mon Jun 25 00:01:59 2012 +0300 @@ -119,8 +119,8 @@ client_send_tagline(cmd, "OK No quota."); else { client_send_line(client, str_c(quotaroot_reply)); - o_stream_send(client->output, str_data(quota_reply), - str_len(quota_reply)); + o_stream_nsend(client->output, str_data(quota_reply), + str_len(quota_reply)); client_send_tagline(cmd, "OK Getquotaroot completed."); } return TRUE; @@ -156,8 +156,8 @@ quota_reply = t_str_new(128); quota_reply_write(quota_reply, cmd->client->user, owner, root); - o_stream_send(cmd->client->output, str_data(quota_reply), - str_len(quota_reply)); + o_stream_nsend(cmd->client->output, str_data(quota_reply), + str_len(quota_reply)); client_send_tagline(cmd, "OK Getquota completed."); return TRUE; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/plugins/zlib/doveadm-zlib.c --- a/src/plugins/zlib/doveadm-zlib.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/plugins/zlib/doveadm-zlib.c Mon Jun 25 00:01:59 2012 +0300 @@ -118,7 +118,7 @@ if (ret < 0) i_fatal("read(stdin) failed: %m"); - o_stream_send(client->output, buf, ret); + o_stream_nsend(client->output, buf, ret); } static void server_input(struct client *client) @@ -170,6 +170,7 @@ client.fd = fd; client.input = i_stream_create_fd(fd, (size_t)-1, FALSE); client.output = o_stream_create_fd(fd, 0, FALSE); + o_stream_set_no_error_handling(client.output, TRUE); client.io_client = io_add(STDIN_FILENO, IO_READ, client_input, &client); client.io_server = io_add(fd, IO_READ, server_input, &client); master_service_run(master_service, NULL); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/plugins/zlib/ostream-bzlib.c --- a/src/plugins/zlib/ostream-bzlib.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/plugins/zlib/ostream-bzlib.c Mon Jun 25 00:01:59 2012 +0300 @@ -24,7 +24,7 @@ { struct bzlib_ostream *zstream = (struct bzlib_ostream *)stream; - o_stream_flush(&zstream->ostream.ostream); + (void)o_stream_flush(&zstream->ostream.ostream); (void)BZ2_bzCompressEnd(&zstream->zs); } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/plugins/zlib/ostream-zlib.c --- a/src/plugins/zlib/ostream-zlib.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/plugins/zlib/ostream-zlib.c Mon Jun 25 00:01:59 2012 +0300 @@ -31,7 +31,7 @@ { struct zlib_ostream *zstream = (struct zlib_ostream *)stream; - o_stream_flush(&zstream->ostream.ostream); + (void)o_stream_flush(&zstream->ostream.ostream); (void)deflateEnd(&zstream->zs); } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/pop3-login/pop3-proxy.c --- a/src/pop3-login/pop3-proxy.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/pop3-login/pop3-proxy.c Mon Jun 25 00:01:59 2012 +0300 @@ -40,7 +40,7 @@ i_assert(client->common.proxy_ttl > 0); if (client->proxy_xclient) { /* remote supports XCLIENT, send it */ - (void)o_stream_send_str(output, t_strdup_printf( + o_stream_nsend_str(output, t_strdup_printf( "XCLIENT ADDR=%s PORT=%u SESSION=%s TTL=%u\r\n", net_ip2addr(&client->common.ip), client->common.remote_port, @@ -61,7 +61,7 @@ /* master user login - use AUTH PLAIN. */ str_append(str, "AUTH PLAIN\r\n"); } - (void)o_stream_send(output, str_data(str), str_len(str)); + o_stream_nsend(output, str_data(str), str_len(str)); } int pop3_proxy_parse_line(struct client *client, const char *line) @@ -91,7 +91,7 @@ if ((ssl_flags & PROXY_SSL_FLAG_STARTTLS) == 0) { proxy_send_login(pop3_client, output); } else { - (void)o_stream_send_str(output, "STLS\r\n"); + o_stream_nsend_str(output, "STLS\r\n"); client->proxy_state = POP3_PROXY_STARTTLS; } return 0; @@ -138,7 +138,7 @@ get_plain_auth(client, str); str_append(str, "\r\n"); } - (void)o_stream_send(output, str_data(str), str_len(str)); + o_stream_nsend(output, str_data(str), str_len(str)); proxy_free_password(client); client->proxy_state = POP3_PROXY_LOGIN2; return 0; @@ -148,7 +148,7 @@ /* Login successful. Send this line to client. */ line = t_strconcat(line, "\r\n", NULL); - (void)o_stream_send_str(client->output, line); + o_stream_nsend_str(client->output, line); client_proxy_finish_destroy_client(client); return 1; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/pop3/pop3-client.c --- a/src/pop3/pop3-client.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/pop3/pop3-client.c Mon Jun 25 00:01:59 2012 +0300 @@ -305,6 +305,7 @@ client->fd_out = fd_out; client->input = i_stream_create_fd(fd_in, MAX_INBUF_SIZE, FALSE); client->output = o_stream_create_fd(fd_out, (size_t)-1, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); o_stream_set_flush_callback(client->output, client_output, client); p_array_init(&client->module_contexts, client->pool, 5); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/pop3/pop3-commands.c --- a/src/pop3/pop3-commands.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/pop3/pop3-commands.c Mon Jun 25 00:01:59 2012 +0300 @@ -391,13 +391,13 @@ if (ctx->last != '\n') { /* didn't end with CRLF */ - (void)o_stream_send(client->output, "\r\n", 2); + o_stream_nsend(client->output, "\r\n", 2); } if (!ctx->in_body && (client->set->parsed_workarounds & WORKAROUND_OE_NS_EOH) != 0) { /* Add the missing end of headers line. */ - (void)o_stream_send(client->output, "\r\n", 2); + o_stream_nsend(client->output, "\r\n", 2); } *ctx->byte_counter += diff -r 3ffdb4bf36d3 -r ca37d1577291 src/replication/aggregator/notify-connection.c --- a/src/replication/aggregator/notify-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/replication/aggregator/notify-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -44,7 +44,7 @@ { struct notify_connection *conn = context; - o_stream_send_str(conn->output, success ? "+\n" : "-\n"); + o_stream_nsend_str(conn->output, success ? "+\n" : "-\n"); notify_connection_unref(conn); } @@ -110,8 +110,10 @@ conn->fd = fd; conn->io = io_add(fd, IO_READ, notify_input, conn); conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); - if (!fifo) + if (!fifo) { conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); + } DLLIST_PREPEND(&conns, conn); } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/replication/aggregator/replicator-connection.c --- a/src/replication/aggregator/replicator-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/replication/aggregator/replicator-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -172,7 +172,8 @@ conn->io = io_add(fd, IO_READ, replicator_input, conn); conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); - (void)o_stream_send_str(conn->output, REPLICATOR_HANDSHAKE); + o_stream_set_no_error_handling(conn->output, TRUE); + o_stream_nsend_str(conn->output, REPLICATOR_HANDSHAKE); o_stream_set_flush_callback(conn->output, replicator_output, conn); } @@ -269,7 +270,7 @@ if (conn->fd != -1 && o_stream_get_buffer_used_size(conn->output) == 0) { /* we can send data immediately */ - o_stream_send(conn->output, data, data_len); + o_stream_nsend(conn->output, data, data_len); } else if (conn->queue[priority]->used + data_len >= REPLICATOR_MEMBUF_MAX_SIZE) { /* FIXME: compress duplicates, start writing to file */ diff -r 3ffdb4bf36d3 -r ca37d1577291 src/replication/replicator/doveadm-connection.c --- a/src/replication/replicator/doveadm-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/replication/replicator/doveadm-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -151,7 +151,8 @@ conn->io = io_add(conn->fd, IO_READ, doveadm_input, conn); conn->input = i_stream_create_fd(conn->fd, MAX_INBUF_SIZE, FALSE); conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE); - o_stream_send_str(conn->output, DOVEADM_HANDSHAKE); + o_stream_set_no_error_handling(conn->output, TRUE); + o_stream_nsend_str(conn->output, DOVEADM_HANDSHAKE); return 0; } @@ -185,7 +186,7 @@ if (full) str_append(cmd, "\t-f"); str_append_c(cmd, '\n'); - o_stream_send(conn->output, str_data(cmd), str_len(cmd)); + o_stream_nsend(conn->output, str_data(cmd), str_len(cmd)); } } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/replication/replicator/notify-connection.c --- a/src/replication/replicator/notify-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/replication/replicator/notify-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -43,7 +43,7 @@ { struct notify_sync_request *request = context; - o_stream_send_str(request->conn->output, t_strdup_printf( + o_stream_nsend_str(request->conn->output, t_strdup_printf( "%c\t%u\n", success ? '+' : '-', request->id)); notify_connection_unref(&request->conn); @@ -141,6 +141,7 @@ conn->fd = fd; conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(conn->output, TRUE); conn->io = io_add(fd, IO_READ, notify_connection_input, conn); conn->queue = queue; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/replication/replicator/replicator-queue.c --- a/src/replication/replicator/replicator-queue.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/replication/replicator/replicator-queue.c Mon Jun 25 00:01:59 2012 +0300 @@ -342,7 +342,7 @@ struct priorityq_item *const *items; unsigned int i, count; string_t *str; - int fd, ret; + int fd, ret = 0; fd = creat(path, 0600); if (fd == -1) { @@ -364,8 +364,10 @@ if (o_stream_send(output, str_data(str), str_len(str)) < 0) break; } - - ret = output->last_failed_errno != 0 ? -1 : 0; + if (o_stream_nfinish(output) < 0) { + i_error("write(%s) failed: %m", path); + ret = -1; + } o_stream_destroy(&output); return ret; } diff -r 3ffdb4bf36d3 -r ca37d1577291 src/ssl-params/main.c --- a/src/ssl-params/main.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/ssl-params/main.c Mon Jun 25 00:01:59 2012 +0300 @@ -46,9 +46,8 @@ struct ostream *output; output = o_stream_create_fd(fd, (size_t)-1, TRUE); - o_stream_send(output, ssl_params->data, ssl_params->used); - - if (o_stream_get_buffer_used_size(output) == 0) + if (o_stream_send(output, ssl_params->data, ssl_params->used) < 0 || + o_stream_get_buffer_used_size(output) == 0) client_deinit(output); else { o_stream_set_flush_callback(output, client_output_flush, diff -r 3ffdb4bf36d3 -r ca37d1577291 src/stats/client-export.c --- a/src/stats/client-export.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/stats/client-export.c Mon Jun 25 00:01:59 2012 +0300 @@ -255,7 +255,7 @@ mail_command_unref(&client->mail_cmd_iter); if (!cmd->header_sent) { - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, "cmd\targs\tsession\tuser\tlast_update"MAIL_STATS_HEADER); cmd->header_sent = TRUE; } @@ -282,8 +282,8 @@ client_export_timeval(cmd->str, &command->last_update); client_export_mail_stats(cmd->str, &command->stats); str_append_c(cmd->str, '\n'); - o_stream_send(client->output, str_data(cmd->str), - str_len(cmd->str)); + o_stream_nsend(client->output, str_data(cmd->str), + str_len(cmd->str)); } if (command != NULL) { @@ -303,7 +303,7 @@ mail_session_unref(&client->mail_session_iter); if (!cmd->header_sent) { - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, "session\tuser\tip\tservice\tpid\tconnected" "\tlast_update\tnum_cmds" MAIL_STATS_HEADER); @@ -335,8 +335,8 @@ str_printfa(cmd->str, "\t%u", session->num_cmds); client_export_mail_stats(cmd->str, &session->stats); str_append_c(cmd->str, '\n'); - o_stream_send(client->output, str_data(cmd->str), - str_len(cmd->str)); + o_stream_nsend(client->output, str_data(cmd->str), + str_len(cmd->str)); } if (session != NULL) { @@ -356,7 +356,7 @@ mail_user_unref(&client->mail_user_iter); if (!cmd->header_sent) { - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, "user\treset_timestamp\tlast_update" "\tnum_logins\tnum_cmds"MAIL_STATS_HEADER); cmd->header_sent = TRUE; @@ -376,8 +376,8 @@ user->num_logins, user->num_cmds); client_export_mail_stats(cmd->str, &user->stats); str_append_c(cmd->str, '\n'); - o_stream_send(client->output, str_data(cmd->str), - str_len(cmd->str)); + o_stream_nsend(client->output, str_data(cmd->str), + str_len(cmd->str)); } if (user != NULL) { @@ -397,7 +397,7 @@ mail_domain_unref(&client->mail_domain_iter); if (!cmd->header_sent) { - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, "domain\treset_timestamp\tlast_update" "\tnum_logins\tnum_cmds"MAIL_STATS_HEADER); cmd->header_sent = TRUE; @@ -417,8 +417,8 @@ domain->num_logins, domain->num_cmds); client_export_mail_stats(cmd->str, &domain->stats); str_append_c(cmd->str, '\n'); - o_stream_send(client->output, str_data(cmd->str), - str_len(cmd->str)); + o_stream_nsend(client->output, str_data(cmd->str), + str_len(cmd->str)); } if (domain != NULL) { @@ -438,7 +438,7 @@ mail_ip_unref(&client->mail_ip_iter); if (!cmd->header_sent) { - o_stream_send_str(client->output, + o_stream_nsend_str(client->output, "ip\treset_timestamp\tlast_update" "\tnum_logins\tnum_cmds"MAIL_STATS_HEADER); cmd->header_sent = TRUE; @@ -459,8 +459,8 @@ str_printfa(cmd->str, "\t%u\t%u", ip->num_logins, ip->num_cmds); client_export_mail_stats(cmd->str, &ip->stats); str_append_c(cmd->str, '\n'); - o_stream_send(client->output, str_data(cmd->str), - str_len(cmd->str)); + o_stream_nsend(client->output, str_data(cmd->str), + str_len(cmd->str)); } if (ip != NULL) { @@ -475,7 +475,7 @@ { if (client->cmd_export->export_iter(client) == 0) return 0; - o_stream_send_str(client->output, "\n"); + o_stream_nsend_str(client->output, "\n"); return 1; } @@ -610,7 +610,7 @@ client->cmd_export = cmd; if (!client_export_iter_init(client)) { /* nothing to export */ - o_stream_send_str(client->output, "\n"); + o_stream_nsend_str(client->output, "\n"); return 1; } client->cmd_more = client_export_more; diff -r 3ffdb4bf36d3 -r ca37d1577291 src/stats/client.c --- a/src/stats/client.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/stats/client.c Mon Jun 25 00:01:59 2012 +0300 @@ -146,6 +146,7 @@ client->io = io_add(fd, IO_READ, client_input, client); client->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); client->output = o_stream_create_fd(fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); o_stream_set_flush_callback(client->output, client_output, client); client->cmd_pool = pool_alloconly_create("cmd pool", 1024); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/stats/mail-server-connection.c --- a/src/stats/mail-server-connection.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/stats/mail-server-connection.c Mon Jun 25 00:01:59 2012 +0300 @@ -16,7 +16,6 @@ struct mail_server_connection { int fd; struct istream *input; - struct ostream *output; struct io *io; }; @@ -88,7 +87,6 @@ conn = i_new(struct mail_server_connection, 1); conn->fd = fd; conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); - conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); conn->io = io_add(fd, IO_READ, mail_server_connection_input, conn); return conn; } @@ -101,7 +99,6 @@ io_remove(&conn->io); i_stream_destroy(&conn->input); - o_stream_destroy(&conn->output); if (close(conn->fd) < 0) i_error("close(conn) failed: %m"); i_free(conn); diff -r 3ffdb4bf36d3 -r ca37d1577291 src/util/rawlog.c --- a/src/util/rawlog.c Sun Jun 24 21:43:48 2012 +0300 +++ b/src/util/rawlog.c Mon Jun 25 00:01:59 2012 +0300 @@ -162,7 +162,7 @@ ret = net_receive(proxy->server_fd, buf, sizeof(buf)); if (ret > 0) { - (void)o_stream_send(proxy->client_output, buf, ret); + o_stream_nsend(proxy->client_output, buf, ret); proxy_write_out(proxy, buf, ret); } else if (ret <= 0) rawlog_proxy_destroy(proxy); @@ -183,7 +183,7 @@ ret = net_receive(proxy->client_in_fd, buf, sizeof(buf)); if (ret > 0) { - (void)o_stream_send(proxy->server_output, buf, ret); + o_stream_nsend(proxy->server_output, buf, ret); proxy_write_in(proxy, buf, ret); } else if (ret < 0) rawlog_proxy_destroy(proxy); @@ -263,13 +263,15 @@ proxy = i_new(struct rawlog_proxy, 1); proxy->server_fd = server_fd; proxy->server_output = o_stream_create_fd(server_fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(proxy->server_output, TRUE); + o_stream_set_flush_callback(proxy->server_output, server_output, proxy); proxy->server_io = io_add(server_fd, IO_READ, server_input, proxy); - o_stream_set_flush_callback(proxy->server_output, server_output, proxy); proxy->client_in_fd = client_in_fd; proxy->client_out_fd = client_out_fd; proxy->client_output = o_stream_create_fd(client_out_fd, (size_t)-1, FALSE); + o_stream_set_no_error_handling(proxy->client_output, TRUE); proxy->client_io = io_add(proxy->client_in_fd, IO_READ, client_input, proxy); o_stream_set_flush_callback(proxy->client_output, client_output, proxy);