Browse Source

ccan: update to get close option to io/fdpass.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 8 years ago
parent
commit
83466b2b32
  1. 2
      ccan/README
  2. 2
      ccan/ccan/io/fdpass/_info
  3. 4
      ccan/ccan/io/fdpass/fdpass.c
  4. 11
      ccan/ccan/io/fdpass/fdpass.h
  5. 2
      ccan/ccan/io/fdpass/test/run.c
  6. 34
      ccan/ccan/io/io.c
  7. 18
      ccan/ccan/io/io.h
  8. 91
      ccan/ccan/io/test/run-30-io_flush_sync.c
  9. 2
      ccan/ccan/str/hex/hex.h
  10. 3
      ccan/ccan/take/_info
  11. 35
      ccan/ccan/take/take.c
  12. 30
      ccan/ccan/take/take.h
  13. 34
      ccan/ccan/take/test/run-debug.c
  14. 1
      ccan/ccan/tal/path/path.c
  15. 19
      ccan/ccan/tal/path/path.h
  16. 1
      ccan/ccan/tal/str/str.c
  17. 25
      ccan/ccan/tal/str/str.h
  18. 1
      ccan/ccan/tal/tal.c
  19. 5
      ccan/ccan/tal/tal.h
  20. 6
      lightningd/gossip/gossip.c
  21. 14
      lightningd/hsm/hsm.c
  22. 10
      lightningd/subd.c
  23. 3
      lightningd/subd.h

2
ccan/README

@ -1,3 +1,3 @@
CCAN imported from http://ccodearchive.net. CCAN imported from http://ccodearchive.net.
CCAN version: init-2354-g9b3f4ef CCAN version: init-2367-ged6dd33

2
ccan/ccan/io/fdpass/_info

@ -58,7 +58,7 @@
* *
* static struct io_plan *send_stdin(struct io_conn *conn, void *unused) * 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) * static void parent(int sockfd)

4
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 0;
return -1; return -1;
} }
if (arg->u2.s)
close(arg->u1.s);
return 1; return 1;
} }
struct io_plan *io_send_fd_(struct io_conn *conn, struct io_plan *io_send_fd_(struct io_conn *conn,
int fd, int fd,
bool fdclose,
struct io_plan *(*next)(struct io_conn *, void *), struct io_plan *(*next)(struct io_conn *, void *),
void *next_arg) void *next_arg)
{ {
struct io_plan_arg *arg = io_plan_arg(conn, IO_OUT); struct io_plan_arg *arg = io_plan_arg(conn, IO_OUT);
arg->u1.s = fd; arg->u1.s = fd;
arg->u2.s = fdclose;
return io_set_plan(conn, IO_OUT, do_fd_send, next, next_arg); return io_set_plan(conn, IO_OUT, do_fd_send, next, next_arg);
} }

11
ccan/ccan/io/fdpass/fdpass.h

@ -7,6 +7,7 @@
* io_send_fd - output plan to send a file descriptor * io_send_fd - output plan to send a file descriptor
* @conn: the connection that plan is for. * @conn: the connection that plan is for.
* @fd: the file descriptor to pass. * @fd: the file descriptor to pass.
* @fdclose: true to close fd after successful sending.
* @next: function to call output is done. * @next: function to call output is done.
* @arg: @next argument * @arg: @next argument
* *
@ -22,17 +23,17 @@
* Example: * Example:
* static struct io_plan *fd_to_conn(struct io_conn *conn, int fd) * static struct io_plan *fd_to_conn(struct io_conn *conn, int fd)
* { * {
* // Write fd, then close. * // Write fd, then close conn.
* return io_send_fd(conn, fd, io_close_cb, NULL); * return io_send_fd(conn, fd, false, io_close_cb, NULL);
* } * }
*/ */
#define io_send_fd(conn, fd, next, arg) \ #define io_send_fd(conn, fd, fdclose, next, arg) \
io_send_fd_((conn), (fd), \ io_send_fd_((conn), (fd), (fdclose), \
typesafe_cb_preargs(struct io_plan *, void *, \ typesafe_cb_preargs(struct io_plan *, void *, \
(next), (arg), struct io_conn *), \ (next), (arg), struct io_conn *), \
(arg)) (arg))
struct io_plan *io_send_fd_(struct io_conn *conn, struct io_plan *io_send_fd_(struct io_conn *conn,
int fd, int fd, bool fdclose,
struct io_plan *(*next)(struct io_conn *, void *), struct io_plan *(*next)(struct io_conn *, void *),
void *arg); void *arg);

2
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) 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) int main(void)

34
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; 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;
}

18
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); 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. * io_time_override - override the normal call for time.
* @nowfn: the function to call. * @nowfn: the function to call.

91
ccan/ccan/io/test/run-30-io_flush_sync.c

@ -0,0 +1,91 @@
#include <ccan/io/io.h>
/* Include the C files directly. */
#include <ccan/io/poll.c>
#include <ccan/io/io.c>
#include <ccan/tap/tap.h>
#include <sys/wait.h>
#include <stdio.h>
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();
}

2
ccan/ccan/str/hex/hex.h

@ -70,4 +70,4 @@ static inline size_t hex_data_size(size_t strlen)
{ {
return strlen / 2; return strlen / 2;
} }
#endif /* PETTYCOIN_HEX_H */ #endif /* CCAN_HEX_H */

3
ccan/ccan/take/_info

@ -18,7 +18,7 @@
* #include <string.h> * #include <string.h>
* *
* // Dumb basename program and driver. * // Dumb basename program and driver.
* static char *base(const char *file) * static char *base(const char *file TAKES)
* { * {
* const char *p = strrchr(file, '/'); * const char *p = strrchr(file, '/');
* if (!p) * if (!p)
@ -53,6 +53,7 @@ int main(int argc, char *argv[])
if (strcmp(argv[1], "depends") == 0) { if (strcmp(argv[1], "depends") == 0) {
printf("ccan/likely\n"); printf("ccan/likely\n");
printf("ccan/str\n");
return 0; return 0;
} }

35
ccan/ccan/take/take.c

@ -1,16 +1,22 @@
/* CC0 (Public domain) - see LICENSE file for details */ /* CC0 (Public domain) - see LICENSE file for details */
#include <ccan/take/take.h> #include <ccan/take/take.h>
#include <ccan/likely/likely.h> #include <ccan/likely/likely.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static const void **takenarr; static const void **takenarr;
static const char **labelarr;
static size_t max_taken, num_taken; static size_t max_taken, num_taken;
static size_t allocfail; static size_t allocfail;
static void (*allocfailfn)(const void *p); 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)) { if (unlikely(num_taken == max_taken)) {
const void **new; const void **new;
@ -25,9 +31,16 @@ void *take_(const void *p)
return (void *)p; return (void *)p;
} }
takenarr = new; takenarr = new;
/* Once labelarr is set, we maintain it. */
if (labelarr)
labelarr = realloc(labelarr,
sizeof(*labelarr) * (max_taken+1));
max_taken++; max_taken++;
} }
if (unlikely(labelarr))
labelarr[num_taken] = label;
takenarr[num_taken++] = p; takenarr[num_taken++] = p;
return (void *)p; return (void *)p;
} }
@ -68,9 +81,23 @@ bool is_taken(const void *p)
return find_taken(p) > 0; 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) void take_cleanup(void)
@ -78,6 +105,8 @@ void take_cleanup(void)
max_taken = num_taken = 0; max_taken = num_taken = 0;
free(takenarr); free(takenarr);
takenarr = NULL; takenarr = NULL;
free(labelarr);
labelarr = NULL;
} }
void take_allocfail(void (*fn)(const void *p)) void take_allocfail(void (*fn)(const void *p))

30
ccan/ccan/take/take.h

@ -3,6 +3,24 @@
#define CCAN_TAKE_H #define CCAN_TAKE_H
#include "config.h" #include "config.h"
#include <stdbool.h> #include <stdbool.h>
#include <ccan/str/str.h>
#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. * 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 * which is extremely useful for chaining functions. It works on
* NULL, for pass-through error handling. * 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() * taken - check (and un-take) a pointer was passed with take()
@ -24,7 +42,7 @@
* *
* Example: * Example:
* // Silly routine to add 1 * // Silly routine to add 1
* static int *add_one(const int *num) * static int *add_one(const int *num TAKES)
* { * {
* int *ret; * int *ret;
* if (taken(num)) * if (taken(num))
@ -60,7 +78,9 @@ bool is_taken(const void *p);
/** /**
* taken_any - are there any taken pointers? * 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: * Example:
* static void cleanup(void) * static void cleanup(void)
@ -68,7 +88,7 @@ bool is_taken(const void *p);
* assert(!taken_any()); * assert(!taken_any());
* } * }
*/ */
bool taken_any(void); const char *taken_any(void);
/** /**
* take_cleanup - remove all taken pointers from list. * take_cleanup - remove all taken pointers from list.
@ -112,5 +132,5 @@ void take_allocfail(void (*fn)(const void *p));
#define take_typeof(ptr) #define take_typeof(ptr)
#endif #endif
void *take_(const void *p); void *take_(const void *p, const char *label);
#endif /* CCAN_TAKE_H */ #endif /* CCAN_TAKE_H */

34
ccan/ccan/take/test/run-debug.c

@ -0,0 +1,34 @@
#include <stdlib.h>
#include <stdbool.h>
#define CCAN_TAKE_DEBUG 1
#include <ccan/take/take.h>
#include <ccan/take/take.c>
#include <ccan/tap/tap.h>
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();
}

1
ccan/ccan/tal/path/path.c

@ -1,7 +1,6 @@
/* Licensed under BSD-MIT - see LICENSE file for details */ /* Licensed under BSD-MIT - see LICENSE file for details */
#include <ccan/tal/path/path.h> #include <ccan/tal/path/path.h>
#include <ccan/str/str.h> #include <ccan/str/str.h>
#include <ccan/take/take.h>
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>

19
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 * Returns NULL and sets errno on error, otherwise returns nul-terminated
* link contents. * 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. * 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 * path with no symbolic links and no extra separators (ie. as per
* realpath). * 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 /. * 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 * terms or remove symlinks, but it does neaten it by removing extraneous
* parts. * 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. * 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 * If @a is an absolute path, return a copy of it. Otherwise, attach
* @a to @base. * @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. * path_pushd - save old dir and change to a new one.
* @ctx: the context to tal the result from * @ctx: the context to tal the result from
* @dir: the directory to return to (can be take()) * @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. * 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", "/"); * char *path = path_rel(NULL, "/tmp", "/");
* assert(strcmp(path, "..") == 0); * 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 * 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: * See Also:
* path_dirname() * 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 * path_dirname - get the directory part of path
@ -114,7 +115,7 @@ char *path_basename(const tal_t *ctx, const char *path);
* See Also: * See Also:
* path_basename() * 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? * path_is_abs - is a path absolute?
@ -149,7 +150,7 @@ bool path_is_dir(const char *path);
* See Also: * See Also:
* strjoin() * 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. * path_ext_off - get offset of the extension within a pathname.

1
ccan/ccan/tal/str/str.c

@ -11,7 +11,6 @@
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <ccan/str/str.h> #include <ccan/str/str.h>
#include <ccan/take/take.h>
char *tal_strdup(const tal_t *ctx, const char *p) char *tal_strdup(const tal_t *ctx, const char *p)
{ {

25
ccan/ccan/tal/str/str.h

@ -14,7 +14,7 @@
* @ctx: NULL, or tal allocated object to be parent. * @ctx: NULL, or tal allocated object to be parent.
* @p: the string to copy (can be take()). * @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. * 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. * 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 * tal_fmt - allocate a formatted string
* @ctx: NULL, or tal allocated object to be parent. * @ctx: NULL, or tal allocated object to be parent.
* @fmt: the printf-style format (can be take()). * @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) * 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()). * @fmt: the printf-style format (can be take()).
* @va: the va_list containing the format args. * @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); 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. * 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) * 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. * 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 * 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()). * @s1: the first string (can be take()).
* @s2: the second 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 { enum strsplit {
STR_EMPTY_OK, STR_EMPTY_OK,
@ -110,7 +110,9 @@ enum strsplit {
* } * }
*/ */
char **tal_strsplit(const tal_t *ctx, 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 { enum strjoin {
STR_TRAIL, STR_TRAIL,
@ -140,7 +142,9 @@ enum strjoin {
* return ret; * 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); enum strjoin flags);
/** /**
@ -183,5 +187,6 @@ char *tal_strjoin(const void *ctx, char *strings[], const char *delim,
* return 0; * 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 */ #endif /* CCAN_STR_TAL_H */

1
ccan/ccan/tal/tal.c

@ -2,7 +2,6 @@
#include <ccan/tal/tal.h> #include <ccan/tal/tal.h>
#include <ccan/compiler/compiler.h> #include <ccan/compiler/compiler.h>
#include <ccan/list/list.h> #include <ccan/list/list.h>
#include <ccan/take/take.h>
#include <ccan/alignof/alignof.h> #include <ccan/alignof/alignof.h>
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>

5
ccan/ccan/tal/tal.h

@ -6,6 +6,7 @@
#include <ccan/likely/likely.h> #include <ccan/likely/likely.h>
#include <ccan/typesafe_cb/typesafe_cb.h> #include <ccan/typesafe_cb/typesafe_cb.h>
#include <ccan/str/str.h> #include <ccan/str/str.h>
#include <ccan/take/take.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdarg.h> #include <stdarg.h>
@ -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, void *tal_alloc_arr_(const tal_t *ctx, size_t bytes, size_t count, bool clear,
bool add_length, const char *label); 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, size_t n, size_t extra, bool add_length,
const char *label); const char *label);
tal_t *tal_steal_(const tal_t *new_parent, const tal_t *t); 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_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_destructor_(const tal_t *ctx, void (*destroy)(void *me));
bool tal_add_destructor2_(const tal_t *ctx, void (*destroy)(void *me, void *arg), bool tal_add_destructor2_(const tal_t *ctx, void (*destroy)(void *me, void *arg),

6
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) 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, static struct io_plan *release_peer(struct io_conn *conn, struct daemon *daemon,

14
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); 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) static struct io_plan *sent_resp(struct io_conn *conn, struct conn_info *ci)
{ {
ci->out = tal_free(ci->out); ci->out = tal_free(ci->out);
if (ci->out_fd != -1) if (ci->out_fd != -1) {
return io_send_fd(conn, ci->out_fd, sent_out_fd, ci); 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); return recv_req(conn, ci);
} }

10
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); 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. */ /* Nothing to do? Wait for msg_enqueue. */
if (!msg) if (!msg)
return msg_queue_wait(conn, &sd->outq, msg_send_next, sd); 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) { if (fromwire_peektype(msg) == STATUS_TRACE) {
const u8 *p = msg + sizeof(be16); const u8 *p = msg + sizeof(be16);
size_t len = tal_count(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); 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); 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->msgcb = msgcb;
sd->fd_in = -1; sd->fd_in = -1;
msg_queue_init(&sd->outq, sd); msg_queue_init(&sd->outq, sd);
sd->fd_to_close = -1;
tal_add_destructor(sd, destroy_subd); tal_add_destructor(sd, destroy_subd);
list_head_init(&sd->reqs); list_head_init(&sd->reqs);

3
lightningd/subd.h

@ -47,9 +47,6 @@ struct subd {
/* Messages queue up here. */ /* Messages queue up here. */
struct msg_queue outq; struct msg_queue outq;
/* FD to close (used when we just sent it). */
int fd_to_close;
/* Callbacks for replies. */ /* Callbacks for replies. */
struct list_head reqs; struct list_head reqs;
}; };

Loading…
Cancel
Save