|
2 | 2 | #include <errno.h> |
3 | 3 | #include <netinet/in.h> |
4 | 4 | #include <poll.h> |
| 5 | +#include <stdlib.h> |
| 6 | +#include <sys/ioctl.h> |
5 | 7 | #include <sys/socket.h> |
| 8 | +#include <unistd.h> |
6 | 9 |
|
7 | 10 | #define TEST(c) \ |
8 | 11 | do { \ |
@@ -73,6 +76,9 @@ int main() { |
73 | 76 | // finishes accepting. |
74 | 77 | int loop_count = 0; |
75 | 78 | while ((server_client == -1 || fds[0].events) && loop_count < 10) { |
| 79 | + if (t_status) |
| 80 | + exit(t_status); |
| 81 | + |
76 | 82 | ++loop_count; |
77 | 83 |
|
78 | 84 | int fd_count = 1; |
@@ -101,23 +107,97 @@ int main() { |
101 | 107 | } |
102 | 108 | ASSERT(loop_count < 10); |
103 | 109 |
|
104 | | - // Send some data from the server to the client. |
105 | | - uint8_t data[5] = {1, 2, 3, 4, 5}; |
106 | | - TEST(send(server_client, data, sizeof(data), 0) == sizeof(data)); |
| 110 | + int one = 1; |
| 111 | + TEST(ioctl(server_client, FIONBIO, &one) != -1); |
| 112 | + |
| 113 | + // Test that we can `recv` what we `send` |
| 114 | + { |
| 115 | + // Send some data from the server to the client. |
| 116 | + uint8_t data[5] = {1, 2, 3, 4, 5}; |
| 117 | + TEST(send(server_client, data, sizeof(data), 0) == sizeof(data)); |
| 118 | + |
| 119 | + fds[0].events = POLLRDNORM; |
| 120 | + errno = 0; |
| 121 | + int count = poll(fds, 1, 100); |
| 122 | + TEST2(count == 1); |
| 123 | + // Now the server has sent something, so the client socket should be |
| 124 | + // readable. |
| 125 | + ASSERT((fds[0].revents & POLLRDNORM) != 0); |
| 126 | + |
| 127 | + uint8_t received[sizeof(data)]; |
| 128 | + TEST(recv(client, received, sizeof(data), 0) == sizeof(data)); |
| 129 | + |
| 130 | + // Assert that what was received matches what was sent. |
| 131 | + for (int i = 0; i < sizeof(data); ++i) { |
| 132 | + ASSERT(received[i] == data[i]); |
| 133 | + } |
| 134 | + } |
107 | 135 |
|
108 | | - fds[0].events = POLLRDNORM; |
109 | | - errno = 0; |
110 | | - int count = poll(fds, 1, 100); |
111 | | - TEST2(count == 1); |
112 | | - // Now the server has sent something, so the client socket should be readable. |
113 | | - ASSERT((fds[0].revents & POLLRDNORM) != 0); |
| 136 | + // Test that we can `read` what we `write` and that neither of them block. |
| 137 | + { |
| 138 | + size_t data_len = 16 * 1024; |
| 139 | + errno = 0; |
| 140 | + uint8_t *received = malloc(data_len); |
| 141 | + TEST2(received != NULL); |
| 142 | + |
| 143 | + // Nothing should be readable, yet. |
| 144 | + TEST(read(client, received, data_len) == -1 && |
| 145 | + (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS)); |
| 146 | + |
| 147 | + errno = 0; |
| 148 | + uint8_t *data = malloc(data_len); |
| 149 | + TEST2(data != NULL); |
| 150 | + |
| 151 | + for (size_t i = 0; i < data_len; ++i) { |
| 152 | + data[i] = 42; |
| 153 | + } |
114 | 154 |
|
115 | | - uint8_t received[sizeof(data)]; |
116 | | - TEST(recv(client, received, sizeof(data), 0) == sizeof(data)); |
| 155 | + // Write until we hit backpressure |
| 156 | + ssize_t write_total = 0; |
| 157 | + while (1) { |
| 158 | + if (t_status) |
| 159 | + exit(t_status); |
117 | 160 |
|
118 | | - // Assert that what was received matches what was sent. |
119 | | - for (int i = 0; i < sizeof(data); ++i) { |
120 | | - ASSERT(received[i] == data[i]); |
| 161 | + errno = 0; |
| 162 | + ssize_t count = write(server_client, data, data_len); |
| 163 | + if (count == -1) { |
| 164 | + TEST2(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS); |
| 165 | + break; |
| 166 | + } else { |
| 167 | + write_total += count; |
| 168 | + } |
| 169 | + } |
| 170 | + |
| 171 | + fds[0].events = POLLRDNORM; |
| 172 | + |
| 173 | + // Read what we wrote |
| 174 | + ssize_t read_total = 0; |
| 175 | + while (1) { |
| 176 | + if (t_status) |
| 177 | + exit(t_status); |
| 178 | + |
| 179 | + { |
| 180 | + errno = 0; |
| 181 | + int count = poll(fds, 1, 100); |
| 182 | + TEST2(count == 1); |
| 183 | + ASSERT((fds[0].revents & POLLRDNORM) != 0); |
| 184 | + } |
| 185 | + |
| 186 | + errno = 0; |
| 187 | + ssize_t count = read(client, received, data_len); |
| 188 | + TEST2(count != -1 || errno == EAGAIN || errno == EWOULDBLOCK || |
| 189 | + errno == EINPROGRESS); |
| 190 | + |
| 191 | + if (count > 0) { |
| 192 | + read_total += count; |
| 193 | + for (ssize_t i = 0; i < count; ++i) { |
| 194 | + ASSERT(received[i] == 42); |
| 195 | + } |
| 196 | + if (read_total == data_len) { |
| 197 | + break; |
| 198 | + } |
| 199 | + } |
| 200 | + } |
121 | 201 | } |
122 | 202 |
|
123 | 203 | return t_status; |
|
0 commit comments