+#define io_write_partial(conn, data, maxlen, lenp, next, arg) \
+ io_write_partial_((conn), (data), (maxlen), (lenp), \
+ typesafe_cb_preargs(struct io_plan *, void *, \
+ (next), (arg), \
+ struct io_conn *), \
+ (arg))
+struct io_plan *io_write_partial_(struct io_conn *conn,
+ const void *data, size_t maxlen, size_t *lenp,
+ struct io_plan *(*next)(struct io_conn *,
+ void*),
+ void *arg);
+
+/**
+ * io_always - plan to immediately call next callback
+ * @conn: the connection that plan is for.
+ * @next: function to call.
+ * @arg: @next argument
+ *
+ * Sometimes it's neater to plan a callback rather than call it directly;
+ * for example, if you only need to read data for one path and not another.
+ *
+ * Example:
+ * static struct io_plan *init_conn_with_nothing(struct io_conn *conn,
+ * void *unused)
+ * {
+ * // Silly example: close on next time around loop.
+ * return io_always(conn, io_close_cb, NULL);
+ * }
+ */
+#define io_always(conn, next, arg) \
+ io_always_((conn), typesafe_cb_preargs(struct io_plan *, void *, \
+ (next), (arg), \
+ struct io_conn *), \
+ (arg))
+
+struct io_plan *io_always_(struct io_conn *conn,
+ struct io_plan *(*next)(struct io_conn *, void *),
+ void *arg);
+
+/**
+ * io_out_always - output plan to immediately call next callback
+ * @conn: the connection that plan is for.
+ * @next: function to call.
+ * @arg: @next argument
+ *
+ * This is a variant of io_always() which uses the output plan; it only
+ * matters if you are using io_duplex, and thus have two plans running at
+ * once.
+ */
+#define io_out_always(conn, next, arg) \
+ io_out_always_((conn), typesafe_cb_preargs(struct io_plan *, void *, \
+ (next), (arg), \
+ struct io_conn *), \
+ (arg))
+
+struct io_plan *io_out_always_(struct io_conn *conn,
+ struct io_plan *(*next)(struct io_conn *,
+ void *),
+ void *arg);
+
+/**
+ * io_sock_shutdown - start socket close process (flushes TCP sockets).
+ * @conn: the connection the plan is for
+ *
+ * Simply closing a TCP socket can lose data; unfortunately you should
+ * shutdown(SHUT_WR) and wait for the other side to see this and close.
+ * Of course, you also need to set a timer, in case it doesn't (you may
+ * already have some responsiveness timer, of course).
+ *
+ * On error, is equivalent to io_close().
+ *
+ * Example:
+ * #include <ccan/timer/timer.h>
+ *
+ * // Timer infra needs wrapper to contain extra data.
+ * struct timeout_timer {
+ * struct timer t;
+ * struct io_conn *conn;
+ * };
+ * static struct timers timers;
+ *
+ * static struct io_plan *flush_and_close(struct io_conn *conn)
+ * {
+ * struct timeout_timer *timeout;
+ * // Freed if conn closes normally.
+ * timeout = tal(conn, struct timeout_timer);
+ * timeout->conn = conn;
+ * timer_addrel(&timers, &timeout->t, time_from_sec(5));
+ * return io_sock_shutdown(conn);
+ * }
+ */
+struct io_plan *io_sock_shutdown(struct io_conn *conn);