committed by
Christian Decker
7 changed files with 230 additions and 9 deletions
@ -1,3 +1,3 @@ |
|||||
CCAN imported from http://ccodearchive.net. |
CCAN imported from http://ccodearchive.net. |
||||
|
|
||||
CCAN version: init-2397-g261b1086 |
CCAN version: init-2398-g7082f7d0 |
||||
|
@ -0,0 +1,75 @@ |
|||||
|
#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> |
||||
|
|
||||
|
static struct io_conn *in_conn; |
||||
|
|
||||
|
static struct io_plan *in_conn_done(struct io_conn *conn, void *unused) |
||||
|
{ |
||||
|
ok1(!io_plan_in_started(conn)); |
||||
|
return io_close(conn); |
||||
|
} |
||||
|
|
||||
|
static struct io_plan *init_in_conn(struct io_conn *conn, char *buf) |
||||
|
{ |
||||
|
ok1(!io_plan_in_started(conn)); |
||||
|
return io_read(conn, buf, 2, in_conn_done, NULL); |
||||
|
} |
||||
|
|
||||
|
static int do_nothing(int fd, struct io_plan_arg *arg) |
||||
|
{ |
||||
|
return 1; |
||||
|
} |
||||
|
|
||||
|
static struct io_plan *dummy_write(struct io_conn *conn, |
||||
|
struct io_plan *(*next) |
||||
|
(struct io_conn *, void *), |
||||
|
void *next_arg) |
||||
|
{ |
||||
|
io_plan_arg(conn, IO_OUT); |
||||
|
return io_set_plan(conn, IO_OUT, do_nothing, next, next_arg); |
||||
|
} |
||||
|
|
||||
|
static struct io_plan *out_post_write(struct io_conn *conn, void *unused) |
||||
|
{ |
||||
|
/* It might not have started yet: try again. */ |
||||
|
if (!io_plan_in_started(in_conn)) |
||||
|
return dummy_write(conn, out_post_write, NULL); |
||||
|
ok1(io_plan_in_started(in_conn)); |
||||
|
|
||||
|
/* Final write, then close */ |
||||
|
return io_write(conn, "2", 1, io_close_cb, NULL); |
||||
|
} |
||||
|
|
||||
|
static struct io_plan *init_out_conn(struct io_conn *conn, void *unused) |
||||
|
{ |
||||
|
ok1(!io_plan_in_started(in_conn)); |
||||
|
return io_write(conn, "1", 1, out_post_write, NULL); |
||||
|
} |
||||
|
|
||||
|
int main(void) |
||||
|
{ |
||||
|
int fds[2]; |
||||
|
const tal_t *ctx = tal(NULL, char); |
||||
|
char *buf = tal_arr(ctx, char, 3); |
||||
|
|
||||
|
/* This is how many tests you plan to run */ |
||||
|
plan_tests(5); |
||||
|
|
||||
|
if (pipe(fds) != 0) |
||||
|
abort(); |
||||
|
|
||||
|
buf[2] = '\0'; |
||||
|
|
||||
|
in_conn = io_new_conn(ctx, fds[0], init_in_conn, buf); |
||||
|
io_new_conn(ctx, fds[1], init_out_conn, NULL); |
||||
|
|
||||
|
io_loop(NULL, NULL); |
||||
|
ok1(strcmp(buf, "12") == 0); |
||||
|
tal_free(ctx); |
||||
|
|
||||
|
/* This exits depending on whether all tests passed */ |
||||
|
return exit_status(); |
||||
|
} |
@ -0,0 +1,100 @@ |
|||||
|
#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> |
||||
|
|
||||
|
static struct io_conn *out_conn; |
||||
|
|
||||
|
/* Write one byte at a time. */ |
||||
|
static int do_slow_write(int fd, struct io_plan_arg *arg) |
||||
|
{ |
||||
|
ssize_t ret = write(fd, arg->u1.cp, 1); |
||||
|
if (ret < 0) |
||||
|
return -1; |
||||
|
|
||||
|
arg->u1.cp += ret; |
||||
|
arg->u2.s -= ret; |
||||
|
return arg->u2.s == 0; |
||||
|
} |
||||
|
|
||||
|
static struct io_plan *io_slow_write(struct io_conn *conn, |
||||
|
const void *data, size_t len, |
||||
|
struct io_plan *(*next)(struct io_conn *, |
||||
|
void *), |
||||
|
void *next_arg) |
||||
|
{ |
||||
|
struct io_plan_arg *arg = io_plan_arg(conn, IO_OUT); |
||||
|
|
||||
|
arg->u1.const_vp = data; |
||||
|
arg->u2.s = len; |
||||
|
|
||||
|
return io_set_plan(conn, IO_OUT, do_slow_write, next, next_arg); |
||||
|
} |
||||
|
|
||||
|
static struct io_plan *out_conn_done(struct io_conn *conn, void *unused) |
||||
|
{ |
||||
|
ok1(!io_plan_out_started(conn)); |
||||
|
return io_close(conn); |
||||
|
} |
||||
|
|
||||
|
static struct io_plan *init_out_conn(struct io_conn *conn, void *unused) |
||||
|
{ |
||||
|
ok1(!io_plan_out_started(conn)); |
||||
|
return io_slow_write(conn, "12", 2, out_conn_done, NULL); |
||||
|
} |
||||
|
|
||||
|
static int do_nothing(int fd, struct io_plan_arg *arg) |
||||
|
{ |
||||
|
return 1; |
||||
|
} |
||||
|
|
||||
|
static struct io_plan *dummy_read(struct io_conn *conn, |
||||
|
struct io_plan *(*next) |
||||
|
(struct io_conn *, void *), |
||||
|
void *next_arg) |
||||
|
{ |
||||
|
io_plan_arg(conn, IO_IN); |
||||
|
return io_set_plan(conn, IO_IN, do_nothing, next, next_arg); |
||||
|
} |
||||
|
|
||||
|
static struct io_plan *in_post_read(struct io_conn *conn, void *buf) |
||||
|
{ |
||||
|
/* It might not have started yet: try again. */ |
||||
|
if (!io_plan_out_started(out_conn)) |
||||
|
return dummy_read(conn, in_post_read, NULL); |
||||
|
ok1(io_plan_out_started(out_conn)); |
||||
|
|
||||
|
/* Final read, then close */ |
||||
|
return io_read(conn, (char *)buf+1, 1, io_close_cb, NULL); |
||||
|
} |
||||
|
|
||||
|
static struct io_plan *init_in_conn(struct io_conn *conn, char *buf) |
||||
|
{ |
||||
|
return io_read(conn, buf, 1, in_post_read, buf); |
||||
|
} |
||||
|
|
||||
|
int main(void) |
||||
|
{ |
||||
|
int fds[2]; |
||||
|
const tal_t *ctx = tal(NULL, char); |
||||
|
char *buf = tal_arr(ctx, char, 3); |
||||
|
|
||||
|
/* This is how many tests you plan to run */ |
||||
|
plan_tests(4); |
||||
|
|
||||
|
if (pipe(fds) != 0) |
||||
|
abort(); |
||||
|
|
||||
|
buf[2] = '\0'; |
||||
|
|
||||
|
io_new_conn(ctx, fds[0], init_in_conn, buf); |
||||
|
out_conn = io_new_conn(ctx, fds[1], init_out_conn, NULL); |
||||
|
|
||||
|
io_loop(NULL, NULL); |
||||
|
ok1(strcmp(buf, "12") == 0); |
||||
|
tal_free(ctx); |
||||
|
|
||||
|
/* This exits depending on whether all tests passed */ |
||||
|
return exit_status(); |
||||
|
} |
Loading…
Reference in new issue