]> git.ozlabs.org Git - ccan/blob - ccan/io/test/run-09-connect.c
base64: fix for unsigned chars (e.g. ARM).
[ccan] / ccan / io / test / run-09-connect.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 #include <sys/wait.h>
7 #include <stdio.h>
8
9 #define PORT "65009"
10
11 static struct io_listener *l;
12 static struct data *d2;
13
14 struct data {
15         int state;
16         char buf[10];
17 };
18
19 static struct io_plan *closer(struct io_conn *conn, struct data *d)
20 {
21         d->state++;
22         return io_close(conn);
23 }
24
25 static struct io_plan *connected(struct io_conn *conn, struct data *d2)
26 {
27         ok1(d2->state == 0);
28         d2->state++;
29         return io_read(conn, d2->buf, sizeof(d2->buf), closer, d2);
30 }
31
32 static struct io_plan *init_conn(struct io_conn *conn, struct data *d)
33 {
34         ok1(d->state == 0);
35         d->state++;
36         io_close_listener(l);
37
38         return io_write(conn, d->buf, sizeof(d->buf), closer, d);
39 }
40
41 static int make_listen_fd(const char *port, struct addrinfo **info)
42 {
43         int fd, on = 1;
44         struct addrinfo *addrinfo, hints;
45
46         memset(&hints, 0, sizeof(hints));
47         hints.ai_family = AF_UNSPEC;
48         hints.ai_socktype = SOCK_STREAM;
49         hints.ai_flags = AI_PASSIVE;
50         hints.ai_protocol = 0;
51
52         if (getaddrinfo(NULL, port, &hints, &addrinfo) != 0)
53                 return -1;
54
55         fd = socket(addrinfo->ai_family, addrinfo->ai_socktype,
56                     addrinfo->ai_protocol);
57         if (fd < 0)
58                 return -1;
59
60         setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
61         if (bind(fd, addrinfo->ai_addr, addrinfo->ai_addrlen) != 0) {
62                 close(fd);
63                 return -1;
64         }
65         if (listen(fd, 1) != 0) {
66                 close(fd);
67                 return -1;
68         }
69         *info = addrinfo;
70         return fd;
71 }
72
73 static struct io_plan *setup_connect(struct io_conn *conn,
74                                      struct addrinfo *addrinfo)
75 {
76         d2 = malloc(sizeof(*d2));
77         d2->state = 0;
78         return io_connect(conn, addrinfo, connected, d2);
79 }
80
81 int main(void)
82 {
83         struct data *d = malloc(sizeof(*d));
84         struct addrinfo *addrinfo;
85         int fd;
86
87         /* This is how many tests you plan to run */
88         plan_tests(8);
89         d->state = 0;
90         memset(d->buf, 'a', sizeof(d->buf));
91         fd = make_listen_fd(PORT, &addrinfo);
92         ok1(fd >= 0);
93         l = io_new_listener(NULL, fd, init_conn, d);
94         ok1(l);
95
96         fd = socket(addrinfo->ai_family, addrinfo->ai_socktype,
97                     addrinfo->ai_protocol);
98         ok1(io_new_conn(NULL, fd, setup_connect, addrinfo));
99
100         ok1(io_loop(NULL, NULL) == NULL);
101         ok1(d->state == 2);
102         ok1(d2->state == 2);
103
104         freeaddrinfo(addrinfo);
105         free(d);
106         free(d2);
107
108         /* This exits depending on whether all tests passed */
109         return exit_status();
110 }