]> git.ozlabs.org Git - ccan/commitdiff
ccan/io: fix occasional immediate close after io_shutdown()
authorRusty Russell <rusty@rustcorp.com.au>
Mon, 29 Sep 2025 01:37:01 +0000 (11:07 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Mon, 29 Sep 2025 01:37:01 +0000 (11:07 +0930)
If we're doing a duplex connection, we could be still trying to write:
that will fail (since we called shutdown on the write side), and we'll
respond by closing the socket.

The reason we're doing shutdown() is to ensure the final bytes are
written: doing a close() breaks this, and so the result is lost final
bytes.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ccan/io/io.c

index 58ae19bdbd83dc91ea9954020b6fd10798106ea6..178ab01bcf956679eb657bd568820f8a2ba03e3a 100644 (file)
@@ -583,8 +583,13 @@ struct io_plan *io_sock_shutdown(struct io_conn *conn)
        if (shutdown(io_conn_fd(conn), SHUT_WR) != 0)
                return io_close(conn);
 
-       /* And leave unset .*/
-       return &conn->plan[IO_IN];
+       /* We need to make sure we don't try to write again, so
+        * "wait" on something which will never be woken.
+        *
+        * In the duplex case, we can call io_sock_shutdown on the
+        * input side, while io_write is going on on the output side.
+        * Then we will try to write, fail, and immediately close. */
+       return io_wait_dir(conn, io_sock_shutdown, IO_OUT, io_never, NULL);
 }
 
 bool io_flush_sync(struct io_conn *conn)