diff --git a/common/daemon_conn.c b/common/daemon_conn.c index 25bbac2bc..e775544cc 100644 --- a/common/daemon_conn.c +++ b/common/daemon_conn.c @@ -1,4 +1,5 @@ #include "config.h" +#include #include #include #include @@ -8,6 +9,7 @@ struct daemon_conn { /* Last message we received */ u8 *msg_in; + int fd_in; /* Queue of outgoing messages */ struct msg_queue *out; @@ -17,11 +19,13 @@ struct daemon_conn { /* Callback for incoming messages */ struct io_plan *(*recv)(struct io_conn *conn, const u8 *, void *); + /* Callback with fd */ + struct io_plan *(*recv_fd)(struct io_conn *conn, const u8 *, int, void *); /* Called whenever we've cleared the msg_out queue. */ void (*outq_empty)(void *); - /* Arg for both callbacks. */ + /* Arg for all three callbacks. */ void *arg; }; @@ -40,6 +44,26 @@ struct io_plan *daemon_conn_read_next(struct io_conn *conn, return io_read_wire(conn, dc, &dc->msg_in, handle_read, dc); } +static struct io_plan *handle_recv_fd(struct io_conn *conn, + struct daemon_conn *dc) +{ + return dc->recv_fd(conn, dc->msg_in, dc->fd_in, dc->arg); +} + +struct io_plan *daemon_conn_read_with_fd_(struct io_conn *conn, + struct daemon_conn *dc, + struct io_plan *(*recv_fd)(struct io_conn *, + const u8 *, + int fd, + void *), + void *arg) +{ + /* We only get this for the type! */ + assert(arg == dc->arg); + dc->recv_fd = recv_fd; + return io_recv_fd(conn, &dc->fd_in, handle_recv_fd, dc); +} + static struct io_plan *daemon_conn_write_next(struct io_conn *conn, struct daemon_conn *dc) { diff --git a/common/daemon_conn.h b/common/daemon_conn.h index 3b0a8b3e8..3996cc398 100644 --- a/common/daemon_conn.h +++ b/common/daemon_conn.h @@ -50,6 +50,28 @@ void daemon_conn_send_fd(struct daemon_conn *dc, int fd); struct io_plan *daemon_conn_read_next(struct io_conn *conn, struct daemon_conn *dc); +/** + * daemon_conn_read_with_fd - Read a file descriptor, call again. + * (arg must be same as daemon_conn_new!) + * When recv() wants an fd with this message. + */ +#define daemon_conn_read_with_fd(conn, dc, recv_fd, arg) \ + daemon_conn_read_with_fd_((conn), (dc), \ + typesafe_cb_preargs(struct io_plan *, void *, \ + (recv_fd), (arg), \ + struct io_conn *, \ + const u8 *, \ + int), \ + (arg)) + +struct io_plan *daemon_conn_read_with_fd_(struct io_conn *conn, + struct daemon_conn *dc, + struct io_plan *(*recv_fd)(struct io_conn *, + const u8 *, + int fd, + void *), + void *arg); + /** * daemon_conn_sync_flush - Flush connection by sending all messages now.. */