]> git.ozlabs.org Git - ccan/blob - ccan/io/test/run-44-io_plan_out_started.c
io: query whether io_plan in/out have started.
[ccan] / ccan / io / test / run-44-io_plan_out_started.c
1 #include <ccan/io/io.h>
2 /* Include the C files directly. */
3 #include <ccan/io/poll.c>
4 #include <ccan/io/io.c>
5 #include <ccan/tap/tap.h>
6
7 static struct io_conn *out_conn;
8
9 /* Write one byte at a time. */
10 static int do_slow_write(int fd, struct io_plan_arg *arg)
11 {
12         ssize_t ret = write(fd, arg->u1.cp, 1);
13         if (ret < 0)
14                 return -1;
15
16         arg->u1.cp += ret;
17         arg->u2.s -= ret;
18         return arg->u2.s == 0;
19 }
20
21 static struct io_plan *io_slow_write(struct io_conn *conn,
22                                      const void *data, size_t len,
23                                      struct io_plan *(*next)(struct io_conn *,
24                                                              void *),
25                                      void *next_arg)
26 {
27         struct io_plan_arg *arg = io_plan_arg(conn, IO_OUT);
28
29         arg->u1.const_vp = data;
30         arg->u2.s = len;
31
32         return io_set_plan(conn, IO_OUT, do_slow_write, next, next_arg);
33 }
34
35 static struct io_plan *out_conn_done(struct io_conn *conn, void *unused)
36 {
37         ok1(!io_plan_out_started(conn));
38         return io_close(conn);
39 }
40
41 static struct io_plan *init_out_conn(struct io_conn *conn, void *unused)
42 {
43         ok1(!io_plan_out_started(conn));
44         return io_slow_write(conn, "12", 2, out_conn_done, NULL);
45 }
46
47 static int do_nothing(int fd, struct io_plan_arg *arg)
48 {
49         return 1;
50 }
51
52 static struct io_plan *dummy_read(struct io_conn *conn,
53                                   struct io_plan *(*next)
54                                   (struct io_conn *, void *),
55                                   void *next_arg)
56 {
57         io_plan_arg(conn, IO_IN);
58         return io_set_plan(conn, IO_IN, do_nothing, next, next_arg);
59 }
60
61 static struct io_plan *in_post_read(struct io_conn *conn, void *buf)
62 {
63         /* It might not have started yet: try again. */
64         if (!io_plan_out_started(out_conn))
65                 return dummy_read(conn, in_post_read, NULL);
66         ok1(io_plan_out_started(out_conn));
67
68         /* Final read, then close */
69         return io_read(conn, (char *)buf+1, 1, io_close_cb, NULL);
70 }
71
72 static struct io_plan *init_in_conn(struct io_conn *conn, char *buf)
73 {
74         return io_read(conn, buf, 1, in_post_read, buf);
75 }
76
77 int main(void)
78 {
79         int fds[2];
80         const tal_t *ctx = tal(NULL, char);
81         char *buf = tal_arr(ctx, char, 3);
82
83         /* This is how many tests you plan to run */
84         plan_tests(4);
85
86         if (pipe(fds) != 0)
87                 abort();
88
89         buf[2] = '\0';
90
91         io_new_conn(ctx, fds[0], init_in_conn, buf);
92         out_conn = io_new_conn(ctx, fds[1], init_out_conn, NULL);
93
94         io_loop(NULL, NULL);
95         ok1(strcmp(buf, "12") == 0);
96         tal_free(ctx);
97
98         /* This exits depending on whether all tests passed */
99         return exit_status();
100 }