From 80886cda8a87695525228675ba558866c55c6b5b Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 4 Jul 2017 10:17:02 +0930 Subject: [PATCH] daemon_conn: fix daemon_conn_sync_flush. We need to set fd to blocking before trying to sync write. Use io_fd_block() elsewhere, too. Signed-off-by: Rusty Russell --- lightningd/daemon_conn.c | 19 ++++++++++++++----- lightningd/new_connection.c | 14 +------------- lightningd/peer_failed.c | 3 ++- lightningd/subd.c | 15 +-------------- 4 files changed, 18 insertions(+), 33 deletions(-) diff --git a/lightningd/daemon_conn.c b/lightningd/daemon_conn.c index a66f69a23..7353bf7b4 100644 --- a/lightningd/daemon_conn.c +++ b/lightningd/daemon_conn.c @@ -35,21 +35,30 @@ struct io_plan *daemon_conn_write_next(struct io_conn *conn, bool daemon_conn_sync_flush(struct daemon_conn *dc) { const u8 *msg; + int daemon_fd; /* Flush any current packet. */ if (!io_flush_sync(dc->conn)) return false; + /* Make fd blocking for the duration */ + daemon_fd = io_conn_fd(dc->conn); + if (!io_fd_block(daemon_fd, true)) + return false; + /* Flush existing messages. */ while ((msg = msg_dequeue(&dc->out)) != NULL) { int fd = msg_extract_fd(msg); if (fd >= 0) { - if (!fdpass_send(io_conn_fd(dc->conn), fd)) - return false; - } else if (!wire_sync_write(io_conn_fd(dc->conn), take(msg))) - return false; + if (!fdpass_send(daemon_fd, fd)) + break; + } else if (!wire_sync_write(daemon_fd, take(msg))) + break; } - return true; + io_fd_block(daemon_fd, false); + + /* Success iff we flushed them all. */ + return msg == NULL; } static struct io_plan *daemon_conn_start(struct io_conn *conn, diff --git a/lightningd/new_connection.c b/lightningd/new_connection.c index 5b9f0ee38..c4a24f1b0 100644 --- a/lightningd/new_connection.c +++ b/lightningd/new_connection.c @@ -41,18 +41,6 @@ static void connection_destroy(struct connection *c) command_fail(c->cmd, "Failed to connect to peer"); } -static void set_blocking(int fd, bool block) -{ - int flags = fcntl(fd, F_GETFL); - - if (block) - flags &= ~O_NONBLOCK; - else - flags |= O_NONBLOCK; - - fcntl(fd, F_SETFL, flags); -} - static void PRINTF_FMT(3,4) connection_failed(struct connection *c, struct log *log, const char *fmt, ...) @@ -202,7 +190,7 @@ static struct io_plan *hsm_then_handshake(struct io_conn *conn, fatal("Could not read fd from HSM: %s", strerror(errno)); /* Make sure connection fd is blocking */ - set_blocking(connfd, true); + io_fd_block(connfd, true); /* Give handshake daemon the hsm fd. */ handshaked = new_subd(ld, ld, diff --git a/lightningd/peer_failed.c b/lightningd/peer_failed.c index d118ef6cb..c5b2709c2 100644 --- a/lightningd/peer_failed.c +++ b/lightningd/peer_failed.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -35,7 +36,7 @@ void peer_failed(int peer_fd, struct crypto_state *cs, msg = towire_error(errmsg, channel_id, (const u8 *)errmsg); /* This is only best-effort; don't block. */ - fcntl(peer_fd, F_SETFL, fcntl(peer_fd, F_GETFL) | O_NONBLOCK); + io_fd_block(peer_fd, false); sync_crypto_write(cs, peer_fd, take(msg)); status_failed(error_code, "%s", errmsg); diff --git a/lightningd/subd.c b/lightningd/subd.c index 391065322..da7d90218 100644 --- a/lightningd/subd.c +++ b/lightningd/subd.c @@ -27,19 +27,6 @@ static bool move_fd(int from, int to) return true; } -/* FIXME: Expose the ccan/io version? */ -static void set_blocking(int fd, bool block) -{ - int flags = fcntl(fd, F_GETFL); - - if (block) - flags &= ~O_NONBLOCK; - else - flags |= O_NONBLOCK; - - fcntl(fd, F_SETFL, flags); -} - struct subd_req { struct list_node list; @@ -281,7 +268,7 @@ static struct io_plan *read_fds(struct io_conn *conn, struct subd *sd) /* Don't trust subd to set it blocking. */ for (i = 0; i < tal_count(sd->fds_in); i++) - set_blocking(sd->fds_in[i], true); + io_fd_block(sd->fds_in[i], true); return sd_msg_read(conn, sd); } return io_recv_fd(conn, &sd->fds_in[sd->num_fds_in_read++],