diff --git a/ccan/README b/ccan/README index d642ecf0a..d75a4c10d 100644 --- a/ccan/README +++ b/ccan/README @@ -1,3 +1,3 @@ CCAN imported from http://ccodearchive.net. -CCAN version: init-2354-g9b3f4ef +CCAN version: init-2367-ged6dd33 diff --git a/ccan/ccan/io/fdpass/_info b/ccan/ccan/io/fdpass/_info index 406b2f5c2..ba09025aa 100644 --- a/ccan/ccan/io/fdpass/_info +++ b/ccan/ccan/io/fdpass/_info @@ -58,7 +58,7 @@ * * static struct io_plan *send_stdin(struct io_conn *conn, void *unused) * { - * return io_send_fd(conn, STDIN_FILENO, io_close_cb, NULL); + * return io_send_fd(conn, STDIN_FILENO, false, io_close_cb, NULL); * } * * static void parent(int sockfd) diff --git a/ccan/ccan/io/fdpass/fdpass.c b/ccan/ccan/io/fdpass/fdpass.c index 11208a9b6..63c462236 100644 --- a/ccan/ccan/io/fdpass/fdpass.c +++ b/ccan/ccan/io/fdpass/fdpass.c @@ -12,17 +12,21 @@ static int do_fd_send(int fd, struct io_plan_arg *arg) return 0; return -1; } + if (arg->u2.s) + close(arg->u1.s); return 1; } struct io_plan *io_send_fd_(struct io_conn *conn, int fd, + bool fdclose, struct io_plan *(*next)(struct io_conn *, void *), void *next_arg) { struct io_plan_arg *arg = io_plan_arg(conn, IO_OUT); arg->u1.s = fd; + arg->u2.s = fdclose; return io_set_plan(conn, IO_OUT, do_fd_send, next, next_arg); } diff --git a/ccan/ccan/io/fdpass/fdpass.h b/ccan/ccan/io/fdpass/fdpass.h index 366ff3521..533bc840f 100644 --- a/ccan/ccan/io/fdpass/fdpass.h +++ b/ccan/ccan/io/fdpass/fdpass.h @@ -7,6 +7,7 @@ * io_send_fd - output plan to send a file descriptor * @conn: the connection that plan is for. * @fd: the file descriptor to pass. + * @fdclose: true to close fd after successful sending. * @next: function to call output is done. * @arg: @next argument * @@ -22,17 +23,17 @@ * Example: * static struct io_plan *fd_to_conn(struct io_conn *conn, int fd) * { - * // Write fd, then close. - * return io_send_fd(conn, fd, io_close_cb, NULL); + * // Write fd, then close conn. + * return io_send_fd(conn, fd, false, io_close_cb, NULL); * } */ -#define io_send_fd(conn, fd, next, arg) \ - io_send_fd_((conn), (fd), \ +#define io_send_fd(conn, fd, fdclose, next, arg) \ + io_send_fd_((conn), (fd), (fdclose), \ typesafe_cb_preargs(struct io_plan *, void *, \ (next), (arg), struct io_conn *), \ (arg)) struct io_plan *io_send_fd_(struct io_conn *conn, - int fd, + int fd, bool fdclose, struct io_plan *(*next)(struct io_conn *, void *), void *arg); diff --git a/ccan/ccan/io/fdpass/test/run.c b/ccan/ccan/io/fdpass/test/run.c index d2021e827..642db0844 100644 --- a/ccan/ccan/io/fdpass/test/run.c +++ b/ccan/ccan/io/fdpass/test/run.c @@ -28,7 +28,7 @@ static struct io_plan *try_writing(struct io_conn *conn, int *pfd) static struct io_plan *send_fd(struct io_conn *conn, int *pfd) { - return io_send_fd(conn, pfd[0], try_writing, pfd); + return io_send_fd(conn, pfd[0], true, try_writing, pfd); } int main(void) diff --git a/ccan/ccan/io/io.c b/ccan/ccan/io/io.c index 68b95e824..f298af707 100644 --- a/ccan/ccan/io/io.c +++ b/ccan/ccan/io/io.c @@ -483,3 +483,37 @@ struct io_plan *io_set_plan(struct io_conn *conn, enum io_direction dir, return plan; } + +bool io_flush_sync(struct io_conn *conn) +{ + struct io_plan *plan = &conn->plan[IO_OUT]; + bool ok; + + /* Not writing? Nothing to do. */ + if (plan->status != IO_POLLING) + return true; + + /* Synchronous please. */ + set_blocking(io_conn_fd(conn), true); + +again: + switch (plan->io(conn->fd.fd, &plan->arg)) { + case -1: + ok = false; + break; + /* Incomplete, try again. */ + case 0: + goto again; + case 1: + ok = true; + /* In case they come back. */ + set_always(conn, IO_OUT, plan->next, plan->next_arg); + break; + default: + /* IO should only return -1, 0 or 1 */ + abort(); + } + + set_blocking(io_conn_fd(conn), false); + return ok; +} diff --git a/ccan/ccan/io/io.h b/ccan/ccan/io/io.h index 1664df65f..fe42b5373 100644 --- a/ccan/ccan/io/io.h +++ b/ccan/ccan/io/io.h @@ -673,6 +673,24 @@ void *io_loop(struct timers *timers, struct timer **expired); */ int io_conn_fd(const struct io_conn *conn); +/** + * io_flush_sync - (synchronously) complete any outstanding output. + * @conn: the connection. + * + * This is generally used as an emergency escape, for example when we + * want to write an error message on a socket before terminating, but it may + * be in the middle of existing I/O. We don't want to service any other + * IO, either. + * + * This returns true if all pending output is complete, false on error. + * The next callback is not called on the conn, but will be as soon as + * io_loop() is called. + * + * See Also: + * io_close_taken_fd + */ +bool io_flush_sync(struct io_conn *conn); + /** * io_time_override - override the normal call for time. * @nowfn: the function to call. diff --git a/ccan/ccan/io/test/run-30-io_flush_sync.c b/ccan/ccan/io/test/run-30-io_flush_sync.c new file mode 100644 index 000000000..3ff8ff7b8 --- /dev/null +++ b/ccan/ccan/io/test/run-30-io_flush_sync.c @@ -0,0 +1,91 @@ +#include +/* Include the C files directly. */ +#include +#include +#include +#include +#include + +static size_t bytes_written; + +/* Should be called multiple times, since only writes 1 byte. */ +static int do_controlled_write(int fd, struct io_plan_arg *arg) +{ + ssize_t ret; + + ret = write(fd, arg->u1.cp, 1); + if (ret < 0) + return -1; + bytes_written += ret; + arg->u1.cp += ret; + arg->u2.s -= ret; + return arg->u2.s == 0; +} + +static int do_error(int fd, struct io_plan_arg *arg) +{ + errno = 1001; + return -1; +} + +static struct io_plan *conn_wait(struct io_conn *conn, void *unused) +{ + return io_wait(conn, conn, io_never, NULL); +} + +static struct io_plan *init_conn_writer(struct io_conn *conn, const char *str) +{ + struct io_plan_arg *arg = io_plan_arg(conn, IO_OUT); + + arg->u1.const_vp = str; + arg->u2.s = strlen(str); + + return io_set_plan(conn, IO_OUT, do_controlled_write, conn_wait, NULL); +} + +static struct io_plan *init_conn_reader(struct io_conn *conn, void *dst) +{ + /* Never actually succeeds. */ + return io_read(conn, dst, 1000, io_never, NULL); +} + +static struct io_plan *init_conn_error(struct io_conn *conn, void *unused) +{ + io_plan_arg(conn, IO_OUT); + return io_set_plan(conn, IO_OUT, do_error, io_never, NULL); +} + +int main(void) +{ + int fd = open("/dev/null", O_RDWR); + const tal_t *ctx = tal(NULL, char); + struct io_conn *conn; + + /* This is how many tests you plan to run */ + plan_tests(9); + + conn = io_new_conn(ctx, fd, init_conn_writer, "hello"); + ok1(bytes_written == 0); + + ok1(io_flush_sync(conn)); + ok1(bytes_written == strlen("hello")); + + /* This won't do anything */ + ok1(io_flush_sync(conn)); + ok1(bytes_written == strlen("hello")); + + /* It's reading, this won't do anything. */ + conn = io_new_conn(ctx, fd, init_conn_reader, ctx); + ok1(io_flush_sync(conn)); + ok1(bytes_written == strlen("hello")); + + /* Now test error state. */ + conn = io_new_conn(ctx, fd, init_conn_error, ctx); + ok1(!io_flush_sync(conn)); + ok1(errno == 1001); + + tal_free(ctx); + + /* This exits depending on whether all tests passed */ + return exit_status(); +} diff --git a/ccan/ccan/str/hex/hex.h b/ccan/ccan/str/hex/hex.h index 0a0d5c5aa..624a77b10 100644 --- a/ccan/ccan/str/hex/hex.h +++ b/ccan/ccan/str/hex/hex.h @@ -70,4 +70,4 @@ static inline size_t hex_data_size(size_t strlen) { return strlen / 2; } -#endif /* PETTYCOIN_HEX_H */ +#endif /* CCAN_HEX_H */ diff --git a/ccan/ccan/take/_info b/ccan/ccan/take/_info index fcb4f318a..c8cc4ac99 100644 --- a/ccan/ccan/take/_info +++ b/ccan/ccan/take/_info @@ -18,7 +18,7 @@ * #include * * // Dumb basename program and driver. - * static char *base(const char *file) + * static char *base(const char *file TAKES) * { * const char *p = strrchr(file, '/'); * if (!p) @@ -53,6 +53,7 @@ int main(int argc, char *argv[]) if (strcmp(argv[1], "depends") == 0) { printf("ccan/likely\n"); + printf("ccan/str\n"); return 0; } diff --git a/ccan/ccan/take/take.c b/ccan/ccan/take/take.c index 73e5c29d2..c628aac0d 100644 --- a/ccan/ccan/take/take.c +++ b/ccan/ccan/take/take.c @@ -1,16 +1,22 @@ /* CC0 (Public domain) - see LICENSE file for details */ #include #include +#include #include #include static const void **takenarr; +static const char **labelarr; static size_t max_taken, num_taken; static size_t allocfail; static void (*allocfailfn)(const void *p); -void *take_(const void *p) +void *take_(const void *p, const char *label) { + /* Overallocate: it's better than risking calloc returning NULL! */ + if (unlikely(label && !labelarr)) + labelarr = calloc(max_taken+1, sizeof(*labelarr)); + if (unlikely(num_taken == max_taken)) { const void **new; @@ -25,9 +31,16 @@ void *take_(const void *p) return (void *)p; } takenarr = new; + /* Once labelarr is set, we maintain it. */ + if (labelarr) + labelarr = realloc(labelarr, + sizeof(*labelarr) * (max_taken+1)); max_taken++; } + if (unlikely(labelarr)) + labelarr[num_taken] = label; takenarr[num_taken++] = p; + return (void *)p; } @@ -68,9 +81,23 @@ bool is_taken(const void *p) return find_taken(p) > 0; } -bool taken_any(void) +const char *taken_any(void) { - return num_taken != 0; + static char pointer_buf[32]; + + if (num_taken == 0) + return NULL; + + /* We're *allowed* to have some with labels, some without. */ + if (labelarr) { + size_t i; + for (i = 0; i < num_taken; i++) + if (labelarr[i]) + return labelarr[i]; + } + + sprintf(pointer_buf, "%p", takenarr[0]); + return pointer_buf; } void take_cleanup(void) @@ -78,6 +105,8 @@ void take_cleanup(void) max_taken = num_taken = 0; free(takenarr); takenarr = NULL; + free(labelarr); + labelarr = NULL; } void take_allocfail(void (*fn)(const void *p)) diff --git a/ccan/ccan/take/take.h b/ccan/ccan/take/take.h index b6ac4a9f0..8950c6b5b 100644 --- a/ccan/ccan/take/take.h +++ b/ccan/ccan/take/take.h @@ -3,6 +3,24 @@ #define CCAN_TAKE_H #include "config.h" #include +#include + +#ifdef CCAN_TAKE_DEBUG +#define TAKE_LABEL(p) __FILE__ ":" stringify(__LINE__) ":" stringify(p) +#else +#define TAKE_LABEL(p) NULL +#endif + +/** + * TAKES - annotate a formal parameter as being take()-able + * + * This doesn't do anything, but useful for documentation. + * + * Example: + * void print_string(const char *str TAKES); + * + */ +#define TAKES /** * take - record a pointer to be consumed by the function its handed to. @@ -12,7 +30,7 @@ * which is extremely useful for chaining functions. It works on * NULL, for pass-through error handling. */ -#define take(p) (take_typeof(p) take_((p))) +#define take(p) (take_typeof(p) take_((p), TAKE_LABEL(p))) /** * taken - check (and un-take) a pointer was passed with take() @@ -24,7 +42,7 @@ * * Example: * // Silly routine to add 1 - * static int *add_one(const int *num) + * static int *add_one(const int *num TAKES) * { * int *ret; * if (taken(num)) @@ -60,7 +78,9 @@ bool is_taken(const void *p); /** * taken_any - are there any taken pointers? * - * Mainly useful for debugging take() leaks. + * Mainly useful for debugging take() leaks. With CCAN_TAKE_DEBUG, returns + * the label where the pointer was passed to take(), otherwise returns + * a static char buffer with the pointer value in it. NULL if none are taken. * * Example: * static void cleanup(void) @@ -68,7 +88,7 @@ bool is_taken(const void *p); * assert(!taken_any()); * } */ -bool taken_any(void); +const char *taken_any(void); /** * take_cleanup - remove all taken pointers from list. @@ -112,5 +132,5 @@ void take_allocfail(void (*fn)(const void *p)); #define take_typeof(ptr) #endif -void *take_(const void *p); +void *take_(const void *p, const char *label); #endif /* CCAN_TAKE_H */ diff --git a/ccan/ccan/take/test/run-debug.c b/ccan/ccan/take/test/run-debug.c new file mode 100644 index 000000000..a9dda6e2a --- /dev/null +++ b/ccan/ccan/take/test/run-debug.c @@ -0,0 +1,34 @@ +#include +#include + +#define CCAN_TAKE_DEBUG 1 +#include +#include +#include + +int main(void) +{ + const char *p = "hi"; + + plan_tests(14); + + /* We can take NULL. */ + ok1(take(NULL) == NULL); + ok1(is_taken(NULL)); + ok1(strstr(taken_any(), "run-debug.c:16:")); + ok1(taken(NULL)); /* Undoes take() */ + ok1(!is_taken(NULL)); + ok1(!taken(NULL)); + ok1(!taken_any()); + + /* We can take a real pointer. */ + ok1(take(p) == p); + ok1(is_taken(p)); + ok1(strends(taken_any(), "run-debug.c:25:p")); + ok1(taken(p)); /* Undoes take() */ + ok1(!is_taken(p)); + ok1(!taken(p)); + ok1(!taken_any()); + + return exit_status(); +} diff --git a/ccan/ccan/tal/path/path.c b/ccan/ccan/tal/path/path.c index 93362c754..362152d29 100644 --- a/ccan/ccan/tal/path/path.c +++ b/ccan/ccan/tal/path/path.c @@ -1,7 +1,6 @@ /* Licensed under BSD-MIT - see LICENSE file for details */ #include #include -#include #include #include #include diff --git a/ccan/ccan/tal/path/path.h b/ccan/ccan/tal/path/path.h index 65d539c11..5678fd1a9 100644 --- a/ccan/ccan/tal/path/path.h +++ b/ccan/ccan/tal/path/path.h @@ -20,7 +20,7 @@ char *path_cwd(const tal_t *ctx); * Returns NULL and sets errno on error, otherwise returns nul-terminated * link contents. */ -char *path_readlink(const tal_t *ctx, const char *link); +char *path_readlink(const tal_t *ctx, const char *link TAKES); /** * path_canon - return the canonical absolute pathname. @@ -31,7 +31,7 @@ char *path_readlink(const tal_t *ctx, const char *link); * path with no symbolic links and no extra separators (ie. as per * realpath). */ -char *path_canon(const tal_t *ctx, const char *a); +char *path_canon(const tal_t *ctx, const char *a TAKES); /** * path_simplify - remove double-/, ./ and some ../, plus trailing /. @@ -42,7 +42,7 @@ char *path_canon(const tal_t *ctx, const char *a); * terms or remove symlinks, but it does neaten it by removing extraneous * parts. */ -char *path_simplify(const tal_t *ctx, const char *a); +char *path_simplify(const tal_t *ctx, const char *a TAKES); /** * path_join - attach one path to another. @@ -53,14 +53,14 @@ char *path_simplify(const tal_t *ctx, const char *a); * If @a is an absolute path, return a copy of it. Otherwise, attach * @a to @base. */ -char *path_join(const tal_t *ctx, const char *base, const char *a); +char *path_join(const tal_t *ctx, const char *base TAKES, const char *a TAKES); /** * path_pushd - save old dir and change to a new one. * @ctx: the context to tal the result from * @dir: the directory to return to (can be take()) */ -struct path_pushd *path_pushd(const tal_t *ctx, const char *dir); +struct path_pushd *path_pushd(const tal_t *ctx, const char *dir TAKES); /** * path_popd - return to old, path_pushd dir. @@ -83,7 +83,8 @@ bool path_popd(struct path_pushd *olddir); * char *path = path_rel(NULL, "/tmp", "/"); * assert(strcmp(path, "..") == 0); */ -char *path_rel(const tal_t *ctx, const char *fromdir, const char *to); +char *path_rel(const tal_t *ctx, + const char *fromdir TAKES, const char *to TAKES); /** * path_basename - get trailing filename part of path @@ -102,7 +103,7 @@ char *path_rel(const tal_t *ctx, const char *fromdir, const char *to); * See Also: * path_dirname() */ -char *path_basename(const tal_t *ctx, const char *path); +char *path_basename(const tal_t *ctx, const char *path TAKES); /** * path_dirname - get the directory part of path @@ -114,7 +115,7 @@ char *path_basename(const tal_t *ctx, const char *path); * See Also: * path_basename() */ -char *path_dirname(const tal_t *ctx, const char *path); +char *path_dirname(const tal_t *ctx, const char *path TAKES); /** * path_is_abs - is a path absolute? @@ -149,7 +150,7 @@ bool path_is_dir(const char *path); * See Also: * strjoin() */ -char **path_split(const tal_t *ctx, const char *path); +char **path_split(const tal_t *ctx, const char *path TAKES); /** * path_ext_off - get offset of the extension within a pathname. diff --git a/ccan/ccan/tal/str/str.c b/ccan/ccan/tal/str/str.c index 7adb9ef5a..4b3b11aa6 100644 --- a/ccan/ccan/tal/str/str.c +++ b/ccan/ccan/tal/str/str.c @@ -11,7 +11,6 @@ #include #include #include -#include char *tal_strdup(const tal_t *ctx, const char *p) { diff --git a/ccan/ccan/tal/str/str.h b/ccan/ccan/tal/str/str.h index 5147ca2d4..ec853defc 100644 --- a/ccan/ccan/tal/str/str.h +++ b/ccan/ccan/tal/str/str.h @@ -14,7 +14,7 @@ * @ctx: NULL, or tal allocated object to be parent. * @p: the string to copy (can be take()). */ -char *tal_strdup(const tal_t *ctx, const char *p); +char *tal_strdup(const tal_t *ctx, const char *p TAKES); /** * tal_strndup - duplicate a limited amount of a string. @@ -24,14 +24,14 @@ char *tal_strdup(const tal_t *ctx, const char *p); * * Always gives a nul-terminated string, with strlen() <= @n. */ -char *tal_strndup(const tal_t *ctx, const char *p, size_t n); +char *tal_strndup(const tal_t *ctx, const char *p TAKES, size_t n); /** * tal_fmt - allocate a formatted string * @ctx: NULL, or tal allocated object to be parent. * @fmt: the printf-style format (can be take()). */ -char *tal_fmt(const tal_t *ctx, const char *fmt, ...) PRINTF_FMT(2,3); +char *tal_fmt(const tal_t *ctx, const char *fmt TAKES, ...) PRINTF_FMT(2,3); /** * tal_vfmt - allocate a formatted string (va_list version) @@ -39,7 +39,7 @@ char *tal_fmt(const tal_t *ctx, const char *fmt, ...) PRINTF_FMT(2,3); * @fmt: the printf-style format (can be take()). * @va: the va_list containing the format args. */ -char *tal_vfmt(const tal_t *ctx, const char *fmt, va_list ap) +char *tal_vfmt(const tal_t *ctx, const char *fmt TAKES, va_list ap) PRINTF_FMT(2,0); /** @@ -49,7 +49,7 @@ char *tal_vfmt(const tal_t *ctx, const char *fmt, va_list ap) * * Returns false on allocation failure. */ -bool tal_append_fmt(char **baseptr, const char *fmt, ...) PRINTF_FMT(2,3); +bool tal_append_fmt(char **baseptr, const char *fmt TAKES, ...) PRINTF_FMT(2,3); /** * tal_append_vfmt - append a formatted string to a talloc string (va_list) @@ -59,7 +59,7 @@ bool tal_append_fmt(char **baseptr, const char *fmt, ...) PRINTF_FMT(2,3); * * Returns false on allocation failure. */ -bool tal_append_vfmt(char **baseptr, const char *fmt, va_list ap); +bool tal_append_vfmt(char **baseptr, const char *fmt TAKES, va_list ap); /** * tal_strcat - join two strings together @@ -67,7 +67,7 @@ bool tal_append_vfmt(char **baseptr, const char *fmt, va_list ap); * @s1: the first string (can be take()). * @s2: the second string (can be take()). */ -char *tal_strcat(const tal_t *ctx, const char *s1, const char *s2); +char *tal_strcat(const tal_t *ctx, const char *s1 TAKES, const char *s2 TAKES); enum strsplit { STR_EMPTY_OK, @@ -110,7 +110,9 @@ enum strsplit { * } */ char **tal_strsplit(const tal_t *ctx, - const char *string, const char *delims, enum strsplit flag); + const char *string TAKES, + const char *delims TAKES, + enum strsplit flag); enum strjoin { STR_TRAIL, @@ -140,7 +142,9 @@ enum strjoin { * return ret; * } */ -char *tal_strjoin(const void *ctx, char *strings[], const char *delim, +char *tal_strjoin(const void *ctx, + char *strings[] TAKES, + const char *delim TAKES, enum strjoin flags); /** @@ -183,5 +187,6 @@ char *tal_strjoin(const void *ctx, char *strings[], const char *delim, * return 0; * } */ -bool tal_strreg(const void *ctx, const char *string, const char *regex, ...); +bool tal_strreg(const void *ctx, const char *string TAKES, + const char *regex TAKES, ...); #endif /* CCAN_STR_TAL_H */ diff --git a/ccan/ccan/tal/tal.c b/ccan/ccan/tal/tal.c index 555dd1333..331f7ea5c 100644 --- a/ccan/ccan/tal/tal.c +++ b/ccan/ccan/tal/tal.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include diff --git a/ccan/ccan/tal/tal.h b/ccan/ccan/tal/tal.h index e525a01d1..30c8e7bb9 100644 --- a/ccan/ccan/tal/tal.h +++ b/ccan/ccan/tal/tal.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -351,7 +352,7 @@ tal_t *tal_parent(const tal_t *ctx); * @type: the type (should match type of @p!) * @p: the object to copy (or reparented if take()) */ -#define tal_dup(ctx, type, p) \ +#define tal_dup(ctx, type, p) \ ((type *)tal_dup_((ctx), tal_typechk_(p, type *), \ sizeof(type), 1, 0, \ false, TAL_LABEL(type, ""))) @@ -487,14 +488,14 @@ void *tal_alloc_(const tal_t *ctx, size_t bytes, bool clear, void *tal_alloc_arr_(const tal_t *ctx, size_t bytes, size_t count, bool clear, bool add_length, const char *label); -void *tal_dup_(const tal_t *ctx, const void *p, size_t size, +void *tal_dup_(const tal_t *ctx, const void *p TAKES, size_t size, size_t n, size_t extra, bool add_length, const char *label); tal_t *tal_steal_(const tal_t *new_parent, const tal_t *t); bool tal_resize_(tal_t **ctxp, size_t size, size_t count, bool clear); -bool tal_expand_(tal_t **ctxp, const void *src, size_t size, size_t count); +bool tal_expand_(tal_t **ctxp, const void *src TAKES, size_t size, size_t count); bool tal_add_destructor_(const tal_t *ctx, void (*destroy)(void *me)); bool tal_add_destructor2_(const tal_t *ctx, void (*destroy)(void *me, void *arg), diff --git a/lightningd/gossip/gossip.c b/lightningd/gossip/gossip.c index 71912edd2..3be3e5129 100644 --- a/lightningd/gossip/gossip.c +++ b/lightningd/gossip/gossip.c @@ -406,7 +406,11 @@ static struct io_plan *new_peer(struct io_conn *conn, struct daemon *daemon, static struct io_plan *release_peer_fd(struct io_conn *conn, struct peer *peer) { - return io_send_fd(conn, peer->fd, next_req_in, peer->daemon); + int fd = peer->fd; + + /* This will be closed after sending. */ + peer->fd = -1; + return io_send_fd(conn, fd, true, next_req_in, peer->daemon); } static struct io_plan *release_peer(struct io_conn *conn, struct daemon *daemon, diff --git a/lightningd/hsm/hsm.c b/lightningd/hsm/hsm.c index 00d8aa739..dc844af4f 100644 --- a/lightningd/hsm/hsm.c +++ b/lightningd/hsm/hsm.c @@ -319,17 +319,15 @@ static struct io_plan *recv_req(struct io_conn *conn, struct conn_info *ci) return io_read_wire(conn, ci, &ci->in, ci->received_req, ci); } -static struct io_plan *sent_out_fd(struct io_conn *conn, struct conn_info *ci) -{ - ci->out_fd = -1; - return recv_req(conn, ci); -} - static struct io_plan *sent_resp(struct io_conn *conn, struct conn_info *ci) { ci->out = tal_free(ci->out); - if (ci->out_fd != -1) - return io_send_fd(conn, ci->out_fd, sent_out_fd, ci); + if (ci->out_fd != -1) { + int fd = ci->out_fd; + ci->out_fd = -1; + /* Close after sending */ + return io_send_fd(conn, fd, true, recv_req, ci); + } return recv_req(conn, ci); } diff --git a/lightningd/subd.c b/lightningd/subd.c index bbef63cee..b08ad15aa 100644 --- a/lightningd/subd.c +++ b/lightningd/subd.c @@ -293,11 +293,6 @@ static struct io_plan *msg_send_next(struct io_conn *conn, struct subd *sd) { const u8 *msg = msg_dequeue(&sd->outq); - if (sd->fd_to_close != -1) { - close(sd->fd_to_close); - sd->fd_to_close = -1; - } - /* Nothing to do? Wait for msg_enqueue. */ if (!msg) return msg_queue_wait(conn, &sd->outq, msg_send_next, sd); @@ -306,9 +301,9 @@ static struct io_plan *msg_send_next(struct io_conn *conn, struct subd *sd) if (fromwire_peektype(msg) == STATUS_TRACE) { const u8 *p = msg + sizeof(be16); size_t len = tal_count(msg) - sizeof(be16); - sd->fd_to_close = fromwire_u32(&p, &len); + int fd = fromwire_u32(&p, &len); tal_free(msg); - return io_send_fd(conn, sd->fd_to_close, msg_send_next, sd); + return io_send_fd(conn, fd, true, msg_send_next, sd); } return io_write_wire(conn, take(msg), msg_send_next, sd); } @@ -353,7 +348,6 @@ struct subd *new_subd(const tal_t *ctx, sd->msgcb = msgcb; sd->fd_in = -1; msg_queue_init(&sd->outq, sd); - sd->fd_to_close = -1; tal_add_destructor(sd, destroy_subd); list_head_init(&sd->reqs); diff --git a/lightningd/subd.h b/lightningd/subd.h index 24bbd2f03..b3e61627a 100644 --- a/lightningd/subd.h +++ b/lightningd/subd.h @@ -47,9 +47,6 @@ struct subd { /* Messages queue up here. */ struct msg_queue outq; - /* FD to close (used when we just sent it). */ - int fd_to_close; - /* Callbacks for replies. */ struct list_head reqs; };