Handle channel closure during a receive callback when the ringbuffer wraps.
[utcp] / selftest.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <time.h>
5 #include <errno.h>
6
7 #include "utcp.h"
8
9 struct utcp *a;
10 struct utcp *b;
11 struct utcp_connection *c;
12
13 ssize_t do_recv(struct utcp_connection *x, const void *data, size_t len) {
14         if(!len) {
15                 if(errno) {
16                         fprintf(stderr, "%p Error: %s\n", (void *)x->utcp, strerror(errno));
17                 } else {
18                         fprintf(stderr, "%p Connection closed by peer\n", (void *)x->utcp);
19                 }
20
21                 if(x != c) {
22                         fprintf(stderr, "closing my side too...\n");
23                         utcp_close(x);
24                 }
25
26                 return -1;
27         }
28
29         if(x == c) {
30                 return write(0, data, len);
31         } else {
32                 return utcp_send(x, data, len);
33         }
34 }
35
36 bool do_pre_accept(struct utcp *utcp, uint16_t port) {
37         (void)utcp;
38         fprintf(stderr, "pre-accept\n");
39
40         if(port != 7) {
41                 return false;
42         }
43
44         return true;
45 }
46
47 void do_accept(struct utcp_connection *c, uint16_t port) {
48         (void)port;
49         fprintf(stderr, "accept\n");
50         utcp_accept(c, do_recv, NULL);
51 }
52
53 ssize_t do_send(struct utcp *utcp, const void *data, size_t len) {
54         static int count = 0;
55
56         if(++count > 1000) {
57                 fprintf(stderr, "Too many packets!\n");
58                 abort();
59         }
60
61         if(utcp == a) {
62                 return utcp_recv(b, data, len);
63         } else {
64                 return utcp_recv(a, data, len);
65         }
66 }
67
68 int main(int argc, char *argv[]) {
69         (void)argc;
70         (void)argv;
71
72         srand(time(NULL));
73
74         a = utcp_init(do_accept, do_pre_accept, do_send, NULL);
75         b = utcp_init(NULL, NULL, do_send, NULL);
76
77         fprintf(stderr, "Testing connection to closed port\n\n");
78         c = utcp_connect(b, 6, do_recv, NULL);
79
80         fprintf(stderr, "\nTesting conection to non-listening side\n\n");
81         c = utcp_connect(a, 7, do_recv, NULL);
82
83         fprintf(stderr, "\nTesting connection to open port, close\n\n");
84         c = utcp_connect(b, 7, do_recv, NULL);
85         fprintf(stderr, "closing...\n");
86         utcp_close(c);
87
88         fprintf(stderr, "\nTesting connection to open port, abort\n\n");
89         c = utcp_connect(b, 7, do_recv, NULL);
90         fprintf(stderr, "aborting...\n");
91         utcp_abort(c);
92
93         fprintf(stderr, "\nTesting connection with data transfer\n\n");
94
95         c = utcp_connect(b, 7, do_recv, NULL);
96         ssize_t len = utcp_send(c, "Hello world!\n", 13);
97
98         if(len != 13) {
99                 if(len == -1) {
100                         fprintf(stderr, "Error: %s\n", strerror(errno));
101                 } else {
102                         fprintf(stderr, "Short write %zd!\n", len);
103                 }
104         }
105
106         len = utcp_send(c, "This is a test.\n", 16);
107
108         if(len != 16) {
109                 if(len == -1) {
110                         fprintf(stderr, "Error: %s\n", strerror(errno));
111                 } else {
112                         fprintf(stderr, "Short write %zd!\n", len);
113                 }
114         }
115
116         fprintf(stderr, "closing...\n");
117         utcp_close(c);
118
119         fprintf(stderr, "\nTesting connection with huge data transfer\n\n");
120
121         c = utcp_connect(b, 7, do_recv, NULL);
122         utcp_set_sndbuf(c, 10240);
123         char buf[20480] = "buf";
124
125         len = utcp_send(c, buf, sizeof(buf));
126
127         if(len != 10240) {
128                 fprintf(stderr, "Error: utcp_send() returned %zd, expected 10240\n", len);
129         }
130
131         fprintf(stderr, "closing...\n");
132         utcp_close(c);
133
134         utcp_exit(a);
135         utcp_exit(b);
136
137         return 0;
138 }