io/fdpass: new module for async fd passing.
[ccan] / ccan / io / fdpass / test / run.c
1 #include <ccan/io/fdpass/fdpass.h>
2 /* Include the C files directly. */
3 #include <ccan/io/fdpass/fdpass.c>
4 #include <ccan/tap/tap.h>
5 #include <sys/types.h>
6 #include <sys/socket.h>
7
8 static struct io_plan *try_reading(struct io_conn *conn, int *fd)
9 {
10         char buf[6];
11         ok1(read(*fd, buf, sizeof(buf)) == sizeof(buf));
12         ok1(memcmp(buf, "hello!", sizeof(buf)) == 0);
13         return io_close(conn);
14 }
15
16 static struct io_plan *get_fd(struct io_conn *conn, void *unused)
17 {
18         int *fd = tal(conn, int);
19         return io_recv_fd(conn, fd, try_reading, fd);
20 }
21
22 static struct io_plan *try_writing(struct io_conn *conn, int *pfd)
23 {
24         close(pfd[0]);
25         ok1(write(pfd[1], "hello!", 6) == 6);
26         return io_close(conn);
27 }
28
29 static struct io_plan *send_fd(struct io_conn *conn, int *pfd)
30 {
31         return io_send_fd(conn, pfd[0], try_writing, pfd);
32 }
33
34 int main(void)
35 {
36         int sv[2];
37         int pfd[2];
38
39         plan_tests(5);
40         ok1(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
41         ok1(pipe(pfd) == 0);
42
43         /* Pass read end of pipe to ourselves, test. */
44         io_new_conn(NULL, sv[0], get_fd, NULL);
45         io_new_conn(NULL, sv[1], send_fd, pfd);
46
47         io_loop(NULL, NULL);
48
49         /* This exits depending on whether all tests passed */
50         return exit_status();
51 }