mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
ccan: update to get close option to io/fdpass.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
4bf398c4e7
commit
83466b2b32
@ -1,3 +1,3 @@
|
||||
CCAN imported from http://ccodearchive.net.
|
||||
|
||||
CCAN version: init-2354-g9b3f4ef
|
||||
CCAN version: init-2367-ged6dd33
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
91
ccan/ccan/io/test/run-30-io_flush_sync.c
Normal file
91
ccan/ccan/io/test/run-30-io_flush_sync.c
Normal file
@ -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();
|
||||
}
|
@ -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 */
|
||||
|
@ -18,7 +18,7 @@
|
||||
* #include <string.h>
|
||||
*
|
||||
* // 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;
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,22 @@
|
||||
/* CC0 (Public domain) - see LICENSE file for details */
|
||||
#include <ccan/take/take.h>
|
||||
#include <ccan/likely/likely.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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))
|
||||
|
@ -3,6 +3,24 @@
|
||||
#define CCAN_TAKE_H
|
||||
#include "config.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.
|
||||
@ -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 */
|
||||
|
34
ccan/ccan/take/test/run-debug.c
Normal file
34
ccan/ccan/take/test/run-debug.c
Normal file
@ -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,7 +1,6 @@
|
||||
/* Licensed under BSD-MIT - see LICENSE file for details */
|
||||
#include <ccan/tal/path/path.h>
|
||||
#include <ccan/str/str.h>
|
||||
#include <ccan/take/take.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.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.
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <ccan/str/str.h>
|
||||
#include <ccan/take/take.h>
|
||||
|
||||
char *tal_strdup(const tal_t *ctx, const char *p)
|
||||
{
|
||||
|
@ -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 */
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include <ccan/tal/tal.h>
|
||||
#include <ccan/compiler/compiler.h>
|
||||
#include <ccan/list/list.h>
|
||||
#include <ccan/take/take.h>
|
||||
#include <ccan/alignof/alignof.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <ccan/likely/likely.h>
|
||||
#include <ccan/typesafe_cb/typesafe_cb.h>
|
||||
#include <ccan/str/str.h>
|
||||
#include <ccan/take/take.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user