etc/services - sync with NetBSD-8
[minix.git] / minix / tests / test90.c
blob8fc25fdb7c250eec0652635d6fb33b3ef386c9f9
1 /* Advanced tests for UNIX Domain Sockets - by D.C. van Moolenbroek */
2 /*
3 * This is a somewhat random collection of in-depth tests, complementing the
4 * more general functionality tests in test56. The overall test set is still
5 * by no means expected to be "complete." The subtests are in random order.
6 */
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/wait.h>
10 #include <sys/socket.h>
11 #include <sys/un.h>
12 #include <sys/ioctl.h>
13 #include <sys/sysctl.h>
14 #include <signal.h>
15 #include <unistd.h>
16 #include <fcntl.h>
17 #include <stddef.h>
18 #include <assert.h>
20 #include "common.h"
21 #include "socklib.h"
23 #define ITERATIONS 1
25 #define SOCK_PATH_A "sock_a"
26 #define SOCK_PATH_B "sock_b"
27 #define SOCK_PATH_C "sock_c"
28 #define SOCK_PATH_D "sock_d"
30 #define SOCK_PATH_A_X ".//sock_a"
31 #define SOCK_PATH_A_Y "./././sock_a"
33 #define PRINT_STATS 0
36 * Check that the given returned socket address matches the given path. A NULL
37 * path may be passed in to indicate the result should be for an unbound
38 * socket.
40 static void
41 check_addr(struct sockaddr_un * sun, socklen_t len, const char * path)
44 if (len < offsetof(struct sockaddr_un, sun_path)) e(0);
46 if (sun->sun_family != AF_UNIX) e(0);
47 if (sun->sun_len != len - ((path != NULL) ? 1 : 0)) e(0);
49 len -= offsetof(struct sockaddr_un, sun_path);
51 if (path != NULL) {
52 if (len != strlen(path) + 1) e(0);
53 if (sun->sun_path[len - 1] != '\0') e(0);
54 if (strcmp(sun->sun_path, path)) e(0);
55 } else
56 if (len != 0) e(0);
60 * Get a socket of the given type, bound to the given path. Return the file
61 * descriptor, as well as the bound addres in 'sun'.
63 static int
64 get_bound_socket(int type, const char * path, struct sockaddr_un * sun)
66 int fd;
68 if ((fd = socket(AF_UNIX, type, 0)) < 0) e(0);
70 (void)unlink(path);
72 memset(sun, 0, sizeof(*sun));
73 sun->sun_family = AF_UNIX;
74 strlcpy(sun->sun_path, path, sizeof(sun->sun_path));
76 if (bind(fd, (struct sockaddr *)sun, sizeof(*sun)) != 0) e(0);
78 return fd;
82 * Get a pair of connected sockets.
84 static void
85 get_socket_pair(int type, int fd[2])
87 struct sockaddr_un sunA, sunB;
89 if ((type & ~SOCK_FLAGS_MASK) == SOCK_DGRAM) {
90 fd[0] = get_bound_socket(type, SOCK_PATH_A, &sunA);
91 fd[1] = get_bound_socket(type, SOCK_PATH_B, &sunB);
93 if (connect(fd[0], (struct sockaddr *)&sunB,
94 sizeof(sunB)) != 0) e(0);
95 if (connect(fd[1], (struct sockaddr *)&sunA,
96 sizeof(sunA)) != 0) e(0);
98 if (unlink(SOCK_PATH_A) != 0) e(0);
99 if (unlink(SOCK_PATH_B) != 0) e(0);
100 } else
101 if (socketpair(AF_UNIX, type, 0, fd) != 0) e(0);
105 * Return the receive buffer size of the given socket.
107 static int
108 get_rcvbuf_len(int fd)
110 socklen_t len;
111 int val;
113 len = sizeof(val);
114 if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, &len) != 0) e(0);
116 if (len != sizeof(val)) e(0);
117 if (val <= 0) e(0);
119 return val;
122 static const enum state unix_connect_states[] = {
123 S_NEW, S_N_SHUT_R, S_N_SHUT_W, S_N_SHUT_RW,
124 S_BOUND, S_LISTENING, S_L_SHUT_R, S_L_SHUT_W,
125 S_L_SHUT_RW, S_CONNECTING, S_CONNECTED, S_ACCEPTED,
126 S_SHUT_R, S_SHUT_W, S_SHUT_RW, S_RSHUT_R,
127 S_RSHUT_W, S_RSHUT_RW, S_SHUT2_R, S_SHUT2_W,
128 S_SHUT2_RW, S_PRE_EOF, S_AT_EOF, S_POST_EOF,
129 S_PRE_SHUT_R, S_EOF_SHUT_R, S_POST_SHUT_R, S_PRE_SHUT_W,
130 S_EOF_SHUT_W, S_POST_SHUT_W, S_PRE_SHUT_RW, S_EOF_SHUT_RW,
131 S_POST_SHUT_RW, S_AT_RESET, S_POST_RESET, S_POST_FAILED
133 * It is impossible to generate the S_PRE_RESET state: we can
134 * only generate a reset on a connected socket for which the
135 * other end is pending acceptance, by closing the listening
136 * socket. That means we cannot send data to the connected end
137 * (from the listening socket) before triggering the reset.
139 * It is impossible to generate the S_FAILED state: even a non-
140 * blocking connect will always fail immediately when it cannot
141 * connect to the target.
145 static const int unix_connect_results[][__arraycount(unix_connect_states)] = {
146 [C_ACCEPT] = {
147 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
148 -EINVAL, -EAGAIN, -ECONNABORTED, -ECONNABORTED,
149 -ECONNABORTED, -EINVAL, -EINVAL, -EINVAL,
150 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
151 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
152 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
153 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
154 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
155 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
157 [C_BIND] = {
158 0, 0, 0, 0,
159 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
160 -EINVAL, 0, 0, -EINVAL,
161 0, 0, 0, 0,
162 0, 0, 0, 0,
163 0, 0, 0, 0,
164 0, 0, 0, 0,
165 0, 0, 0, 0,
166 0, 0, 0, 0,
168 [C_CONNECT] = {
169 0, 0, 0, 0,
170 0, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
171 -EOPNOTSUPP, -EALREADY, -EISCONN, -EISCONN,
172 -EISCONN, -EISCONN, -EISCONN, -EISCONN,
173 -EISCONN, -EISCONN, -EISCONN, -EISCONN,
174 -EISCONN, 0, 0, 0,
175 0, 0, 0, 0,
176 0, 0, 0, 0,
177 0, 0, 0, 0,
179 [C_GETPEERNAME] = {
180 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
181 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
182 -ENOTCONN, -ENOTCONN, 0, 0,
183 0, 0, 0, 0,
184 0, 0, 0, 0,
185 0, -ENOTCONN, -ENOTCONN, -ENOTCONN,
186 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
187 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
188 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
190 [C_GETSOCKNAME] = {
191 0, 0, 0, 0,
192 0, 0, 0, 0,
193 0, 0, 0, 0,
194 0, 0, 0, 0,
195 0, 0, 0, 0,
196 0, 0, 0, 0,
197 0, 0, 0, 0,
198 0, 0, 0, 0,
199 0, 0, 0, 0,
201 [C_GETSOCKOPT_ERR] = {
202 0, 0, 0, 0,
203 0, 0, 0, 0,
204 0, 0, 0, 0,
205 0, 0, 0, 0,
206 0, 0, 0, 0,
207 0, 0, 0, 0,
208 0, 0, 0, 0,
209 0, 0, 0, 0,
210 0, -ECONNRESET, 0, 0,
212 [C_GETSOCKOPT_KA] = {
213 0, 0, 0, 0,
214 0, 0, 0, 0,
215 0, 0, 0, 0,
216 0, 0, 0, 0,
217 0, 0, 0, 0,
218 0, 0, 0, 0,
219 0, 0, 0, 0,
220 0, 0, 0, 0,
221 0, 0, 0, 0,
223 [C_GETSOCKOPT_RB] = {
224 0, 0, 0, 0,
225 0, 0, 0, 0,
226 0, 0, 0, 0,
227 0, 0, 0, 0,
228 0, 0, 0, 0,
229 0, 0, 0, 0,
230 0, 0, 0, 0,
231 0, 0, 0, 0,
232 0, 0, 0, 0,
234 [C_IOCTL_NREAD] = {
235 0, 0, 0, 0,
236 0, 0, 0, 0,
237 0, 0, 0, 0,
238 0, 0, 0, 0,
239 0, 0, 0, 0,
240 0, 1, 0, 0,
241 0, 0, 0, 1,
242 0, 0, 0, 0,
243 0, 0, 0, 0,
245 [C_LISTEN] = {
246 -EDESTADDRREQ, -EDESTADDRREQ, -EDESTADDRREQ, -EDESTADDRREQ,
247 0, 0, 0, 0,
248 0, -EINVAL, -EINVAL, -EINVAL,
249 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
250 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
251 -EINVAL, -EDESTADDRREQ, -EDESTADDRREQ, -EDESTADDRREQ,
252 -EDESTADDRREQ, -EDESTADDRREQ, -EDESTADDRREQ, -EDESTADDRREQ,
253 -EDESTADDRREQ, -EDESTADDRREQ, -EDESTADDRREQ, -EDESTADDRREQ,
254 -EDESTADDRREQ, -EDESTADDRREQ, -EDESTADDRREQ, -EDESTADDRREQ,
256 [C_RECV] = {
257 -ENOTCONN, 0, -ENOTCONN, 0,
258 -ENOTCONN, -ENOTCONN, 0, -ENOTCONN,
259 0, -EAGAIN, -EAGAIN, -EAGAIN,
260 0, -EAGAIN, 0, -EAGAIN,
261 0, 0, 0, 0,
262 0, 1, 0, 0,
263 0, 0, 0, 1,
264 0, 0, 0, 0,
265 0, -ECONNRESET, 0, -ENOTCONN,
267 [C_RECVFROM] = {
268 -ENOTCONN, 0, -ENOTCONN, 0,
269 -ENOTCONN, -ENOTCONN, 0, -ENOTCONN,
270 0, -EAGAIN, -EAGAIN, -EAGAIN,
271 0, -EAGAIN, 0, -EAGAIN,
272 0, 0, 0, 0,
273 0, 1, 0, 0,
274 0, 0, 0, 1,
275 0, 0, 0, 0,
276 0, -ECONNRESET, 0, -ENOTCONN,
278 [C_SEND] = {
279 -ENOTCONN, -ENOTCONN, -EPIPE, -EPIPE,
280 -ENOTCONN, -ENOTCONN, -ENOTCONN, -EPIPE,
281 -EPIPE, -EAGAIN, 1, 1,
282 1, -EPIPE, -EPIPE, -EPIPE,
283 1, -EPIPE, -EPIPE, -EPIPE,
284 -EPIPE, -EPIPE, -EPIPE, -EPIPE,
285 -EPIPE, -EPIPE, -EPIPE, -EPIPE,
286 -EPIPE, -EPIPE, -EPIPE, -EPIPE,
287 -EPIPE, -ECONNRESET, -EPIPE, -ENOTCONN,
289 [C_SENDTO] = {
290 -ENOTCONN, -ENOTCONN, -EPIPE, -EPIPE,
291 -ENOTCONN, -ENOTCONN, -ENOTCONN, -EPIPE,
292 -EPIPE, -EAGAIN, 1, 1,
293 1, -EPIPE, -EPIPE, -EPIPE,
294 1, -EPIPE, -EPIPE, -EPIPE,
295 -EPIPE, -EPIPE, -EPIPE, -EPIPE,
296 -EPIPE, -EPIPE, -EPIPE, -EPIPE,
297 -EPIPE, -EPIPE, -EPIPE, -EPIPE,
298 -EPIPE, -ECONNRESET, -EPIPE, -ENOTCONN,
300 [C_SELECT_R] = {
301 1, 1, 1, 1,
302 1, 0, 1, 1,
303 1, 0, 0, 0,
304 1, 0, 1, 0,
305 1, 1, 1, 1,
306 1, 1, 1, 1,
307 1, 1, 1, 1,
308 1, 1, 1, 1,
309 1, 1, 1, 1,
311 [C_SELECT_W] = {
312 1, 1, 1, 1,
313 1, 1, 1, 1,
314 1, 0, 1, 1,
315 1, 1, 1, 1,
316 1, 1, 1, 1,
317 1, 1, 1, 1,
318 1, 1, 1, 1,
319 1, 1, 1, 1,
320 1, 1, 1, 1,
322 [C_SELECT_X] = {
323 0, 0, 0, 0,
324 0, 0, 0, 0,
325 0, 0, 0, 0,
326 0, 0, 0, 0,
327 0, 0, 0, 0,
328 0, 0, 0, 0,
329 0, 0, 0, 0,
330 0, 0, 0, 0,
331 0, 0, 0, 0,
333 [C_SETSOCKOPT_BC] = {
334 0, 0, 0, 0,
335 0, 0, 0, 0,
336 0, 0, 0, 0,
337 0, 0, 0, 0,
338 0, 0, 0, 0,
339 0, 0, 0, 0,
340 0, 0, 0, 0,
341 0, 0, 0, 0,
342 0, 0, 0, 0,
344 [C_SETSOCKOPT_KA] = {
345 0, 0, 0, 0,
346 0, 0, 0, 0,
347 0, 0, 0, 0,
348 0, 0, 0, 0,
349 0, 0, 0, 0,
350 0, 0, 0, 0,
351 0, 0, 0, 0,
352 0, 0, 0, 0,
353 0, 0, 0, 0,
355 [C_SETSOCKOPT_L] = {
356 0, 0, 0, 0,
357 0, 0, 0, 0,
358 0, 0, 0, 0,
359 0, 0, 0, 0,
360 0, 0, 0, 0,
361 0, 0, 0, 0,
362 0, 0, 0, 0,
363 0, 0, 0, 0,
364 0, 0, 0, 0,
366 [C_SETSOCKOPT_RA] = {
367 0, 0, 0, 0,
368 0, 0, 0, 0,
369 0, 0, 0, 0,
370 0, 0, 0, 0,
371 0, 0, 0, 0,
372 0, 0, 0, 0,
373 0, 0, 0, 0,
374 0, 0, 0, 0,
375 0, 0, 0, 0,
377 [C_SHUTDOWN_R] = {
378 0, 0, 0, 0,
379 0, 0, 0, 0,
380 0, 0, 0, 0,
381 0, 0, 0, 0,
382 0, 0, 0, 0,
383 0, 0, 0, 0,
384 0, 0, 0, 0,
385 0, 0, 0, 0,
386 0, 0, 0, 0,
388 [C_SHUTDOWN_RW] = {
389 0, 0, 0, 0,
390 0, 0, 0, 0,
391 0, 0, 0, 0,
392 0, 0, 0, 0,
393 0, 0, 0, 0,
394 0, 0, 0, 0,
395 0, 0, 0, 0,
396 0, 0, 0, 0,
397 0, 0, 0, 0,
399 [C_SHUTDOWN_W] = {
400 0, 0, 0, 0,
401 0, 0, 0, 0,
402 0, 0, 0, 0,
403 0, 0, 0, 0,
404 0, 0, 0, 0,
405 0, 0, 0, 0,
406 0, 0, 0, 0,
407 0, 0, 0, 0,
408 0, 0, 0, 0,
413 * Set up a connection-oriented socket file descriptor in the requested state
414 * and pass it to socklib_sweep_call() along with local and remote addresses
415 * and their length.
417 static int
418 unix_connect_sweep(int domain, int type, int protocol __unused,
419 enum state state, enum call call)
421 struct sockaddr_un sunA, sunB, sunC;
422 char buf[1];
423 socklen_t len;
424 fd_set fds;
425 int r, fd, fd2, fd3, tmpfd, val, fl;
427 (void)unlink(SOCK_PATH_A);
428 (void)unlink(SOCK_PATH_B);
429 (void)unlink(SOCK_PATH_C);
431 memset(&sunA, 0, sizeof(sunA));
432 sunA.sun_family = AF_UNIX;
433 strlcpy(sunA.sun_path, SOCK_PATH_A, sizeof(sunA.sun_path));
435 fd = fd3 = -1;
437 fd2 = get_bound_socket(type | SOCK_NONBLOCK, SOCK_PATH_B, &sunB);
439 if (listen(fd2, 1) == -1) e(0);
441 switch (state) {
442 case S_NEW:
443 case S_N_SHUT_R:
444 case S_N_SHUT_W:
445 case S_N_SHUT_RW:
446 if ((fd = socket(AF_UNIX, type | SOCK_NONBLOCK, 0)) < 0) e(0);
448 switch (state) {
449 case S_N_SHUT_R: if (shutdown(fd, SHUT_RD)) e(0); break;
450 case S_N_SHUT_W: if (shutdown(fd, SHUT_WR)) e(0); break;
451 case S_N_SHUT_RW: if (shutdown(fd, SHUT_RDWR)) e(0); break;
452 default: break;
455 break;
457 case S_BOUND:
458 case S_LISTENING:
459 case S_L_SHUT_R:
460 case S_L_SHUT_W:
461 case S_L_SHUT_RW:
462 fd = get_bound_socket(type | SOCK_NONBLOCK, SOCK_PATH_A,
463 &sunA);
465 if (state == S_BOUND)
466 break;
468 if (listen(fd, 1) == -1) e(0);
470 switch (state) {
471 case S_L_SHUT_R: if (shutdown(fd, SHUT_RD)) e(0); break;
472 case S_L_SHUT_W: if (shutdown(fd, SHUT_WR)) e(0); break;
473 case S_L_SHUT_RW: if (shutdown(fd, SHUT_RDWR)) e(0); break;
474 default: break;
477 break;
479 case S_CONNECTING:
481 * The following block is nonportable. On NetBSD, the
482 * LOCAL_CONNWAIT socket option is present but seems somewhat..
483 * under-tested. On Linux, it is not possible to put a UNIX
484 * domain socket in a connecting state.
486 if ((fd = socket(AF_UNIX, type | SOCK_NONBLOCK, 0)) < 0) e(0);
488 val = 1;
489 if (setsockopt(fd, 0, LOCAL_CONNWAIT, &val, sizeof(val)) != 0)
490 e(0);
492 if (connect(fd, (struct sockaddr *)&sunB, sizeof(sunB)) != -1)
493 e(0);
494 if (errno != EINPROGRESS) e(0);
496 break;
498 case S_CONNECTED:
499 case S_ACCEPTED:
500 case S_SHUT_R:
501 case S_SHUT_W:
502 case S_SHUT_RW:
503 case S_RSHUT_R:
504 case S_RSHUT_W:
505 case S_RSHUT_RW:
506 case S_SHUT2_R:
507 case S_SHUT2_W:
508 case S_SHUT2_RW:
509 if ((fd = socket(AF_UNIX, type | SOCK_NONBLOCK, 0)) < 0) e(0);
511 if (connect(fd, (struct sockaddr *)&sunB, sizeof(sunB)) != 0)
512 e(0);
514 len = sizeof(sunC);
515 if ((fd3 = accept(fd2, (struct sockaddr *)&sunC, &len)) < 0)
516 e(0);
518 if ((fl = fcntl(fd3, F_GETFL)) == -1) e(0);
519 if (fcntl(fd3, F_SETFL, fl | O_NONBLOCK) != 0) e(0);
521 /* Just to make sure, wait for the socket to be connected. */
522 FD_ZERO(&fds);
523 FD_SET(fd, &fds);
524 if (select(fd + 1, NULL, &fds, NULL, NULL) != 1) e(0);
526 switch (state) {
527 case S_SHUT_R:
528 case S_SHUT2_R: if (shutdown(fd, SHUT_RD)) e(0); break;
529 case S_SHUT_W:
530 case S_SHUT2_W: if (shutdown(fd, SHUT_WR)) e(0); break;
531 case S_SHUT_RW:
532 case S_SHUT2_RW: if (shutdown(fd, SHUT_RDWR)) e(0); break;
533 default: break;
536 switch (state) {
537 case S_RSHUT_R:
538 case S_SHUT2_R: if (shutdown(fd3, SHUT_RD)) e(0); break;
539 case S_RSHUT_W:
540 case S_SHUT2_W: if (shutdown(fd3, SHUT_WR)) e(0); break;
541 case S_RSHUT_RW:
542 case S_SHUT2_RW: if (shutdown(fd3, SHUT_RDWR)) e(0); break;
543 default: break;
546 if (state == S_ACCEPTED) {
547 tmpfd = fd;
548 fd = fd3;
549 fd3 = tmpfd;
552 break;
554 case S_PRE_EOF:
555 case S_AT_EOF:
556 case S_POST_EOF:
557 case S_PRE_SHUT_R:
558 case S_EOF_SHUT_R:
559 case S_POST_SHUT_R:
560 case S_PRE_SHUT_W:
561 case S_EOF_SHUT_W:
562 case S_POST_SHUT_W:
563 case S_PRE_SHUT_RW:
564 case S_EOF_SHUT_RW:
565 case S_POST_SHUT_RW:
566 if ((fd = socket(AF_UNIX, type | SOCK_NONBLOCK, 0)) < 0) e(0);
568 if (connect(fd, (struct sockaddr *)&sunB, sizeof(sunB)) != 0)
569 e(0);
571 len = sizeof(sunC);
572 if ((fd3 = accept(fd2, (struct sockaddr *)&sunC, &len)) < 0)
573 e(0);
575 if ((fl = fcntl(fd3, F_GETFL)) == -1) e(0);
576 if (fcntl(fd3, F_SETFL, fl | O_NONBLOCK) != 0) e(0);
578 if (send(fd3, "", 1, 0) != 1) e(0);
580 if (close(fd3) != 0) e(0);
581 fd3 = -1;
583 FD_ZERO(&fds);
584 FD_SET(fd, &fds);
585 if (select(fd + 1, &fds, NULL, NULL, NULL) != 1) e(0);
587 switch (state) {
588 case S_AT_EOF:
589 case S_EOF_SHUT_R:
590 case S_EOF_SHUT_W:
591 case S_EOF_SHUT_RW:
592 if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
593 break;
594 case S_POST_EOF:
595 case S_POST_SHUT_R:
596 case S_POST_SHUT_W:
597 case S_POST_SHUT_RW:
598 if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
599 if (recv(fd, buf, sizeof(buf), 0) != 0) e(0);
600 break;
601 default:
602 break;
605 switch (state) {
606 case S_PRE_SHUT_R:
607 case S_EOF_SHUT_R:
608 case S_POST_SHUT_R: if (shutdown(fd, SHUT_RD)) e(0); break;
609 case S_PRE_SHUT_W:
610 case S_EOF_SHUT_W:
611 case S_POST_SHUT_W: if (shutdown(fd, SHUT_WR)) e(0); break;
612 case S_PRE_SHUT_RW:
613 case S_EOF_SHUT_RW:
614 case S_POST_SHUT_RW: if (shutdown(fd, SHUT_RDWR)) e(0); break;
615 default: break;
618 break;
620 case S_AT_RESET:
621 case S_POST_RESET:
622 if ((fd = socket(AF_UNIX, type | SOCK_NONBLOCK, 0)) < 0) e(0);
624 if (connect(fd, (struct sockaddr *)&sunB, sizeof(sunB)) != 0)
625 e(0);
628 * Closing the listening socket before the connection has been
629 * accepted should generate ECONNRESET on the connected socket.
630 * Well, should.. we choose to do that. So does Linux. NetBSD
631 * just returns EOF for that case. There are really no strong
632 * arguments for either behavior.
634 if (close(fd2) != 0) e(0);
636 if (state == S_POST_RESET)
637 (void)recv(fd, buf, sizeof(buf), 0);
639 /* Recreate the listening socket just for consistency. */
640 fd2 = get_bound_socket(type | SOCK_NONBLOCK, SOCK_PATH_B,
641 &sunB);
643 if (listen(fd2, 1) == -1) e(0);
645 break;
647 case S_POST_FAILED:
648 if ((fd = socket(AF_UNIX, type | SOCK_NONBLOCK, 0)) < 0) e(0);
650 memset(&sunC, 0, sizeof(sunC));
651 sunC.sun_family = AF_UNIX;
652 strlcpy(sunC.sun_path, SOCK_PATH_C, sizeof(sunC.sun_path));
654 r = connect(fd, (struct sockaddr *)&sunC, sizeof(sunC));
655 if (r != -1 || errno != ENOENT)
656 e(0);
658 break;
660 default:
661 e(0);
664 r = socklib_sweep_call(call, fd, (struct sockaddr *)&sunA,
665 (struct sockaddr *)&sunB, sizeof(struct sockaddr_un));
667 if (fd >= 0 && close(fd) != 0) e(0);
668 if (fd2 >= 0 && close(fd2) != 0) e(0);
669 if (fd3 >= 0 && close(fd3) != 0) e(0);
671 (void)unlink(SOCK_PATH_A);
672 (void)unlink(SOCK_PATH_B);
674 return r;
677 static const enum state unix_dgram_states[] = {
678 S_NEW, S_N_SHUT_R, S_N_SHUT_W, S_N_SHUT_RW,
679 S_BOUND, S_CONNECTED, S_SHUT_R, S_SHUT_W,
680 S_SHUT_RW, S_RSHUT_R, S_RSHUT_W, S_RSHUT_RW,
681 S_SHUT2_R, S_SHUT2_W, S_SHUT2_RW, S_PRE_RESET,
682 S_AT_RESET, S_POST_RESET
685 static const int unix_dgram_results[][__arraycount(unix_dgram_states)] = {
686 [C_ACCEPT] = {
687 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
688 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
689 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
690 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
691 -EOPNOTSUPP, -EOPNOTSUPP,
693 [C_BIND] = {
694 0, 0, 0, 0,
695 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
696 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
697 -EINVAL, -EINVAL, -EINVAL, -EINVAL,
698 -EINVAL, -EINVAL,
700 [C_CONNECT] = {
701 0, 0, 0, 0,
702 0, 0, 0, 0,
703 0, 0, 0, 0,
704 0, 0, 0, -ECONNREFUSED,
705 -ECONNREFUSED, -ECONNREFUSED,
707 [C_GETPEERNAME] = {
708 -ENOTCONN, -ENOTCONN, -ENOTCONN, -ENOTCONN,
709 -ENOTCONN, 0, 0, 0,
710 0, 0, 0, 0,
711 0, 0, 0, -ENOTCONN,
712 -ENOTCONN, -ENOTCONN,
714 [C_GETSOCKNAME] = {
715 0, 0, 0, 0,
716 0, 0, 0, 0,
717 0, 0, 0, 0,
718 0, 0, 0, 0,
719 0, 0,
721 [C_GETSOCKOPT_ERR] = {
722 0, 0, 0, 0,
723 0, 0, 0, 0,
724 0, 0, 0, 0,
725 0, 0, 0, -ECONNRESET,
726 -ECONNRESET, 0,
728 [C_GETSOCKOPT_KA] = {
729 0, 0, 0, 0,
730 0, 0, 0, 0,
731 0, 0, 0, 0,
732 0, 0, 0, 0,
733 0, 0,
735 [C_GETSOCKOPT_RB] = {
736 0, 0, 0, 0,
737 0, 0, 0, 0,
738 0, 0, 0, 0,
739 0, 0, 0, 0,
740 0, 0,
742 [C_IOCTL_NREAD] = {
743 0, 0, 0, 0,
744 0, 0, 0, 0,
745 0, 0, 0, 0,
746 0, 0, 0, 1,
747 0, 0,
749 [C_LISTEN] = {
750 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
751 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
752 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
753 -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP, -EOPNOTSUPP,
754 -EOPNOTSUPP, -EOPNOTSUPP,
756 [C_RECV] = {
757 -EAGAIN, 0, -EAGAIN, 0,
758 -EAGAIN, -EAGAIN, 0, -EAGAIN,
759 0, -EAGAIN, -EAGAIN, -EAGAIN,
760 0, -EAGAIN, 0, 1,
761 -ECONNRESET, -EAGAIN,
763 [C_RECVFROM] = {
764 -EAGAIN, 0, -EAGAIN, 0,
765 -EAGAIN, -EAGAIN, 0, -EAGAIN,
766 0, -EAGAIN, -EAGAIN, -EAGAIN,
767 0, -EAGAIN, 0, 1,
768 -ECONNRESET, -EAGAIN,
770 [C_SEND] = {
771 -EDESTADDRREQ, -EDESTADDRREQ, -EPIPE, -EPIPE,
772 -EDESTADDRREQ, 1, 1, -EPIPE,
773 -EPIPE, -ENOBUFS, 1, -ENOBUFS,
774 -ENOBUFS, -EPIPE, -EPIPE, -ECONNRESET,
775 -ECONNRESET, -EDESTADDRREQ,
777 [C_SENDTO] = {
778 1, 1, -EPIPE, -EPIPE,
779 1, 1, 1, -EPIPE,
780 -EPIPE, -ENOBUFS, 1, -ENOBUFS,
781 -ENOBUFS, -EPIPE, -EPIPE, -ECONNRESET,
782 -ECONNRESET, -ECONNREFUSED,
784 [C_SELECT_R] = {
785 0, 1, 0, 1,
786 0, 0, 1, 0,
787 1, 0, 0, 0,
788 1, 0, 1, 1,
789 1, 0,
791 [C_SELECT_W] = {
792 1, 1, 1, 1,
793 1, 1, 1, 1,
794 1, 1, 1, 1,
795 1, 1, 1, 1,
796 1, 1,
798 [C_SELECT_X] = {
799 0, 0, 0, 0,
800 0, 0, 0, 0,
801 0, 0, 0, 0,
802 0, 0, 0, 0,
803 0, 0,
805 [C_SETSOCKOPT_BC] = {
806 0, 0, 0, 0,
807 0, 0, 0, 0,
808 0, 0, 0, 0,
809 0, 0, 0, 0,
810 0, 0,
812 [C_SETSOCKOPT_KA] = {
813 0, 0, 0, 0,
814 0, 0, 0, 0,
815 0, 0, 0, 0,
816 0, 0, 0, 0,
817 0, 0,
819 [C_SETSOCKOPT_L] = {
820 0, 0, 0, 0,
821 0, 0, 0, 0,
822 0, 0, 0, 0,
823 0, 0, 0, 0,
824 0, 0,
826 [C_SETSOCKOPT_RA] = {
827 0, 0, 0, 0,
828 0, 0, 0, 0,
829 0, 0, 0, 0,
830 0, 0, 0, 0,
831 0, 0,
833 [C_SHUTDOWN_R] = {
834 0, 0, 0, 0,
835 0, 0, 0, 0,
836 0, 0, 0, 0,
837 0, 0, 0, 0,
838 0, 0,
840 [C_SHUTDOWN_RW] = {
841 0, 0, 0, 0,
842 0, 0, 0, 0,
843 0, 0, 0, 0,
844 0, 0, 0, 0,
845 0, 0,
847 [C_SHUTDOWN_W] = {
848 0, 0, 0, 0,
849 0, 0, 0, 0,
850 0, 0, 0, 0,
851 0, 0, 0, 0,
852 0, 0,
857 * Set up a datagram socket file descriptor in the requested state and pass it
858 * to socklib_sweep_call() along with local and remote addresses and their
859 * length.
861 static int
862 unix_dgram_sweep(int domain __unused, int type, int protocol __unused,
863 enum state state, enum call call)
865 struct sockaddr_un sunA, sunB;
866 char buf[1];
867 int r, fd, fd2;
869 (void)unlink(SOCK_PATH_A);
870 (void)unlink(SOCK_PATH_B);
872 /* Create a bound remote socket. */
873 fd2 = get_bound_socket(type | SOCK_NONBLOCK, SOCK_PATH_B, &sunB);
875 switch (state) {
876 case S_NEW:
877 case S_N_SHUT_R:
878 case S_N_SHUT_W:
879 case S_N_SHUT_RW:
880 memset(&sunA, 0, sizeof(sunA));
881 sunA.sun_family = AF_UNIX;
882 strlcpy(sunA.sun_path, SOCK_PATH_A, sizeof(sunA.sun_path));
884 if ((fd = socket(AF_UNIX, type | SOCK_NONBLOCK, 0)) < 0)
885 e(0);
887 switch (state) {
888 case S_N_SHUT_R: if (shutdown(fd, SHUT_RD)) e(0); break;
889 case S_N_SHUT_W: if (shutdown(fd, SHUT_WR)) e(0); break;
890 case S_N_SHUT_RW: if (shutdown(fd, SHUT_RDWR)) e(0); break;
891 default: break;
894 break;
896 case S_BOUND:
897 case S_CONNECTED:
898 case S_SHUT_R:
899 case S_SHUT_W:
900 case S_SHUT_RW:
901 case S_RSHUT_R:
902 case S_RSHUT_W:
903 case S_RSHUT_RW:
904 case S_SHUT2_R:
905 case S_SHUT2_W:
906 case S_SHUT2_RW:
907 case S_PRE_RESET:
908 case S_AT_RESET:
909 case S_POST_RESET:
910 fd = get_bound_socket(type | SOCK_NONBLOCK, SOCK_PATH_A,
911 &sunA);
913 if (state == S_BOUND)
914 break;
916 if (connect(fd, (struct sockaddr *)&sunB, sizeof(sunB)) != 0)
917 e(0);
919 switch (state) {
920 case S_SHUT_R:
921 case S_SHUT2_R: if (shutdown(fd, SHUT_RD)) e(0); break;
922 case S_SHUT_W:
923 case S_SHUT2_W: if (shutdown(fd, SHUT_WR)) e(0); break;
924 case S_SHUT_RW:
925 case S_SHUT2_RW: if (shutdown(fd, SHUT_RDWR)) e(0); break;
926 default: break;
929 switch (state) {
930 case S_RSHUT_R:
931 case S_SHUT2_R: if (shutdown(fd2, SHUT_RD)) e(0); break;
932 case S_RSHUT_W:
933 case S_SHUT2_W: if (shutdown(fd2, SHUT_WR)) e(0); break;
934 case S_RSHUT_RW:
935 case S_SHUT2_RW: if (shutdown(fd2, SHUT_RDWR)) e(0); break;
936 case S_PRE_RESET:
937 case S_AT_RESET:
938 case S_POST_RESET:
939 if (sendto(fd2, "", 1, 0, (struct sockaddr *)&sunA,
940 sizeof(sunA)) != 1) e(0);
942 if (close(fd2) != 0) e(0);
943 fd2 = -1;
945 if (state != S_PRE_RESET) {
946 if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
948 if (state == S_POST_RESET) {
949 (void)recv(fd, buf, sizeof(buf), 0);
951 default:
952 break;
955 break;
957 default:
958 fd = -1;
959 e(0);
962 r = socklib_sweep_call(call, fd, (struct sockaddr *)&sunA,
963 (struct sockaddr *)&sunB, sizeof(struct sockaddr_un));
965 if (close(fd) != 0) e(0);
966 if (fd2 != -1 && close(fd2) != 0) e(0);
968 (void)unlink(SOCK_PATH_A);
969 (void)unlink(SOCK_PATH_B);
971 return r;
975 * Sweep test for socket calls versus socket states of all socket types.
977 static void
978 test90a(void)
981 subtest = 1;
983 socklib_sweep(AF_UNIX, SOCK_STREAM, 0, unix_connect_states,
984 __arraycount(unix_connect_states),
985 (const int *)unix_connect_results, unix_connect_sweep);
987 socklib_sweep(AF_UNIX, SOCK_SEQPACKET, 0, unix_connect_states,
988 __arraycount(unix_connect_states),
989 (const int *)unix_connect_results, unix_connect_sweep);
991 socklib_sweep(AF_UNIX, SOCK_DGRAM, 0, unix_dgram_states,
992 __arraycount(unix_dgram_states), (const int *)unix_dgram_results,
993 unix_dgram_sweep);
998 * Test for large sends and receives with MSG_WAITALL.
1000 static void
1001 test90b(void)
1003 int fd[2];
1005 subtest = 2;
1007 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != 0) e(0);
1009 socklib_large_transfers(fd);
1013 * A randomized producer-consumer test for datagram sockets.
1015 static void
1016 sub90c(int type)
1018 char *buf;
1019 time_t t;
1020 socklen_t len, size;
1021 ssize_t r;
1022 pid_t pid;
1023 unsigned int count;
1024 int i, fd[2], rcvlen, status, exp, flags, num, stat[2] = { 0, 0 };
1026 get_socket_pair(type, fd);
1028 size = rcvlen = get_rcvbuf_len(fd[0]);
1030 if ((buf = malloc(size)) == NULL) e(0);
1032 t = time(NULL);
1035 * We vary small versus large (random) send and receive sizes,
1036 * splitting the entire transfer in four phases along those lines.
1038 * In theory, the use of an extra system call and the use of MSG_PEEK
1039 * both contribute to the expectation that the consumer side will fall
1040 * behind the producer. In this case, we cannot vary receive sizes to
1041 * compensate. This not appear to be a major problem here, though.
1043 #define NR_PACKETS (256 * 1024)
1045 pid = fork();
1046 switch (pid) {
1047 case 0:
1048 errct = 0;
1050 if (close(fd[0]) != 0) e(0);
1052 srand48(t + 1);
1054 for (count = 0; count < NR_PACKETS; ) {
1055 if (count < NR_PACKETS / 2)
1056 len = lrand48() % 64;
1057 else
1058 len = lrand48() % size;
1060 num = lrand48() % 16;
1061 flags = 0;
1062 if (num & 1) flags |= MSG_PEEK;
1063 if (num & 2) flags |= MSG_WAITALL;
1064 if (num & 4) flags |= MSG_DONTWAIT;
1065 if (num & 8) {
1067 * Obviously there are race conditions here but
1068 * the returned number should be accurate if
1069 * not zero. Hopefully it's not always zero.
1071 if (ioctl(fd[1], FIONREAD, &exp) != 0) e(0);
1072 if (exp < 0 || exp > rcvlen) e(0);
1073 } else
1074 exp = 0;
1076 stat[0]++;
1079 * A lame approach to preventing unbounded spinning on
1080 * ENOBUFS on the producer side.
1082 if (type == SOCK_DGRAM)
1083 (void)send(fd[1], "", 1, MSG_DONTWAIT);
1085 if ((r = recv(fd[1], buf, len, flags)) == -1) {
1086 if (errno != EWOULDBLOCK) e(0);
1087 if (exp > 0) e(0);
1089 stat[1]++;
1091 continue;
1094 if (exp != 0) {
1095 if (r == len && exp < r) e(0);
1096 else if (r < len && exp != r) e(0);
1099 if (r >= 2 &&
1100 r > ((size_t)(unsigned char)buf[0] << 8) +
1101 (size_t)(unsigned char)buf[1]) e(0);
1103 for (i = 2; i < r; i++)
1104 if (buf[i] != (char)i) e(0);
1106 if (!(flags & MSG_PEEK))
1107 count++;
1110 #if PRINT_STATS
1112 * The second and third numbers should ideally be a large but
1113 * non-dominating fraction of the first one.
1115 printf("RECV: total %d again %d\n", stat[0], stat[1]);
1116 #endif
1118 if (close(fd[1]) != 0) e(0);
1119 exit(errct);
1120 case -1:
1121 e(0);
1124 if (close(fd[1]) != 0) e(0);
1126 srand48(t);
1128 for (count = 0; count < NR_PACKETS; ) {
1129 if (count < NR_PACKETS / 4 ||
1130 (count >= NR_PACKETS / 2 && count < NR_PACKETS * 3 / 4))
1131 len = lrand48() % 64;
1132 else
1133 len = lrand48() % size;
1135 buf[0] = (len >> 8) & 0xff;
1136 buf[1] = len & 0xff;
1137 for (i = 2; i < len; i++)
1138 buf[i] = i;
1140 flags = (lrand48() % 2) ? MSG_DONTWAIT : 0;
1142 r = send(fd[0], buf, len, flags);
1144 if (r != len) {
1145 if (r != -1) e(0);
1147 if (errno != EMSGSIZE && errno != EWOULDBLOCK &&
1148 errno != ENOBUFS) e(0);
1150 if (errno == ENOBUFS || errno == EWOULDBLOCK) {
1152 * As stated above: lame. Ideally we would
1153 * continue only when the receiver side drains
1154 * the queue, but it may block once it has done
1155 * so. Instead, by going through consumer
1156 * "tokens" we will ultimately block here and
1157 * let the receiver catch up.
1159 if (type == SOCK_DGRAM && errno == ENOBUFS)
1160 (void)recv(fd[0], buf, 1, 0);
1162 stat[0]++;
1163 stat[1]++;
1165 continue;
1166 } else
1167 stat[0]++;
1169 if (count % (NR_PACKETS / 4) == 0)
1170 sleep(1);
1172 count++;
1175 #if PRINT_STATS
1177 * The second number should ideally be a large but non-dominating
1178 * fraction of the first one.
1180 printf("SEND: total %d again %d\n", stat[0], stat[1]);
1181 #endif
1183 free(buf);
1185 if (close(fd[0]) != 0) e(0);
1187 if (waitpid(pid, &status, 0) != pid) e(0);
1188 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
1192 * A randomized producer-consumer test. As part of this, we also perform very
1193 * basic bulk functionality tests of FIONREAD, MSG_PEEK, MSG_DONTWAIT, and
1194 * MSG_WAITALL.
1196 static void
1197 test90c(void)
1199 int fd[2];
1201 subtest = 4;
1203 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != 0) e(0);
1205 socklib_producer_consumer(fd);
1207 sub90c(SOCK_SEQPACKET);
1209 sub90c(SOCK_DGRAM);
1213 * Test that immediately accepted non-blocking connect requests to a listening
1214 * socket with LOCAL_CONNWAIT turned on, return OK rather than EINPROGRESS.
1215 * This requires a hack in libsockevent.
1217 static void
1218 test90d(void)
1220 struct sockaddr_un sunA, sunB;
1221 socklen_t len;
1222 pid_t pid;
1223 int fd, fd2, fd3, val, status;
1225 subtest = 4;
1228 * First ensure that a non-blocking connect to a listening socket that
1229 * does not have a accept call blocked on it, fails with EINPROGRESS.
1231 fd = get_bound_socket(SOCK_STREAM, SOCK_PATH_A, &sunA);
1233 val = 1;
1234 if (setsockopt(fd, 0, LOCAL_CONNWAIT, &val, sizeof(val)) != 0) e(0);
1236 if (listen(fd, 1) != 0) e(0);
1238 if ((fd2 = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) < 0) e(0);
1240 if (connect(fd2, (struct sockaddr *)&sunA, sizeof(sunA)) != -1) e(0);
1241 if (errno != EINPROGRESS) e(0);
1243 len = sizeof(sunB);
1244 if ((fd3 = accept(fd, (struct sockaddr *)&sunB, &len)) < 0) e(0);
1245 check_addr(&sunB, len, NULL);
1247 if (close(fd) != 0) e(0);
1248 if (close(fd2) != 0) e(0);
1249 if (close(fd3) != 0) e(0);
1251 if (unlink(SOCK_PATH_A) != 0) e(0);
1254 * Second, ensure that a blocking connect eventually does return
1255 * success if an accept call is made later on.
1257 fd = get_bound_socket(SOCK_STREAM, SOCK_PATH_A, &sunA);
1259 val = 1;
1260 if (setsockopt(fd, 0, LOCAL_CONNWAIT, &val, sizeof(val)) != 0) e(0);
1262 if (listen(fd, 1) != 0) e(0);
1264 pid = fork();
1265 switch (pid) {
1266 case 0:
1267 errct = 0;
1269 sleep(1);
1271 len = sizeof(sunB);
1272 if ((fd2 = accept(fd, (struct sockaddr *)&sunB, &len)) < 0)
1273 e(0);
1274 check_addr(&sunB, len, NULL);
1276 exit(errct);
1277 case -1:
1278 e(0);
1281 if (close(fd) != 0) e(0);
1283 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) e(0);
1285 if (connect(fd, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
1287 if (close(fd) != 0) e(0);
1289 if (unlink(SOCK_PATH_A) != 0) e(0);
1291 if (waitpid(pid, &status, 0) != pid) e(0);
1292 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
1295 * Finally, test the most implementation-complex case: a non-blocking
1296 * connect should succeed (i.e., yield return code 0) immediately if
1297 * there is a accept call blocked on it.
1299 fd = get_bound_socket(SOCK_STREAM, SOCK_PATH_A, &sunA);
1301 val = 1;
1302 if (setsockopt(fd, 0, LOCAL_CONNWAIT, &val, sizeof(val)) != 0) e(0);
1304 if (listen(fd, 1) != 0) e(0);
1306 pid = fork();
1307 switch (pid) {
1308 case 0:
1309 errct = 0;
1311 len = sizeof(sunB);
1312 if ((fd2 = accept(fd, (struct sockaddr *)&sunB, &len)) < 0)
1313 e(0);
1314 check_addr(&sunB, len, SOCK_PATH_B);
1316 exit(errct);
1317 case -1:
1318 e(0);
1321 if (close(fd) != 0) e(0);
1323 sleep(1);
1325 fd = get_bound_socket(SOCK_STREAM | SOCK_NONBLOCK, SOCK_PATH_B, &sunB);
1327 if (connect(fd, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
1329 if (close(fd) != 0) e(0);
1331 if (waitpid(pid, &status, 0) != pid) e(0);
1332 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
1334 if (unlink(SOCK_PATH_A) != 0) e(0);
1335 if (unlink(SOCK_PATH_B) != 0) e(0);
1339 * Test self-connecting datagram sockets.
1341 static void
1342 test90e(void)
1344 struct sockaddr_un sunA, sunB, sunC;
1345 socklen_t len;
1346 char buf[3];
1347 pid_t pid;
1348 int fdA, fdB, val, status;
1350 subtest = 5;
1352 fdA = get_bound_socket(SOCK_DGRAM, SOCK_PATH_A, &sunA);
1353 fdB = get_bound_socket(SOCK_DGRAM, SOCK_PATH_B, &sunB);
1355 /* Connect the socket to itself, and attempt to communicate. */
1356 if (connect(fdA, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
1358 if (send(fdA, "abc", 3, 0) != 3) e(0);
1360 if (recv(fdA, buf, sizeof(buf), 0) != 3) e(0);
1361 if (strncmp(buf, "abc", 3)) e(0);
1363 /* Reconnect the socket to another target. */
1364 if (connect(fdA, (struct sockaddr *)&sunB, sizeof(sunB)) != 0) e(0);
1366 len = sizeof(val);
1367 if (getsockopt(fdA, SOL_SOCKET, SO_ERROR, &val, &len) != 0) e(0);
1368 if (val != 0) e(0);
1370 if (send(fdA, "def", 3, 0) != 3) e(0);
1372 memset(&sunC, 0, sizeof(sunC));
1373 len = sizeof(sunC);
1374 if (recvfrom(fdB, buf, sizeof(buf), 0, (struct sockaddr *)&sunC,
1375 &len) != 3) e(0);
1376 check_addr(&sunC, len, SOCK_PATH_A);
1377 if (strncmp(buf, "def", 3)) e(0);
1379 /* Reconnect the socket to itself again. */
1380 if (connect(fdA, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
1382 len = sizeof(val);
1383 if (getsockopt(fdA, SOL_SOCKET, SO_ERROR, &val, &len) != 0) e(0);
1384 if (val != 0) e(0);
1386 pid = fork();
1387 switch (pid) {
1388 case 0:
1389 errct = 0;
1391 if (recv(fdA, buf, sizeof(buf), 0) != 3) e(0);
1392 if (strncmp(buf, "ghi", 3)) e(0);
1394 exit(errct);
1395 case -1:
1396 e(0);
1399 sleep(1);
1401 if (send(fdA, "ghi", 3, 0) != 3) e(0);
1403 if (waitpid(pid, &status, 0) != pid) e(0);
1404 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
1406 if (close(fdA) != 0) e(0);
1407 if (close(fdB) != 0) e(0);
1409 if (unlink(SOCK_PATH_A) != 0) e(0);
1410 if (unlink(SOCK_PATH_B) != 0) e(0);
1414 * Test multiple blocked calls getting resumed (or not) upon connect(2) success
1415 * or failure. This test uses LOCAL_CONNWAIT. TODO: rewrite this to use
1416 * interprocess communication rather than the current carefully arranged and
1417 * rather brittle timing approach.
1419 static void
1420 sub90f(unsigned int test)
1422 struct sockaddr_un sun;
1423 pid_t pid[4], apid;
1424 char buf[1];
1425 unsigned int i;
1426 socklen_t len;
1427 int r, fd, fd2, fl, val, status;
1429 fd = get_bound_socket(SOCK_STREAM, SOCK_PATH_A, &sun);
1431 val = 1;
1432 if (setsockopt(fd, 0, LOCAL_CONNWAIT, &val, sizeof(val)) != 0) e(0);
1434 if (listen(fd, 1) != 0) e(0);
1436 apid = fork();
1437 switch (apid) {
1438 case 0:
1439 errct = 0;
1441 sleep(3);
1443 if (test < 2) {
1444 len = sizeof(sun);
1445 if ((fd2 = accept(fd, (struct sockaddr *)&sun,
1446 &len)) < 0) e(0);
1448 sleep(2);
1450 if (close(fd2) != 0) e(0);
1453 if (close(fd) != 0) e(0);
1455 exit(errct);
1456 case -1:
1457 e(0);
1460 if (close(fd) != 0) e(0);
1462 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) e(0);
1464 for (i = 0; i < __arraycount(pid); i++) {
1465 pid[i] = fork();
1466 switch (pid[i]) {
1467 case 0:
1468 errct = 0;
1470 sleep((i == 0) ? 1 : 2);
1472 if ((i & 1) == 0) {
1473 r = send(fd, "", 1, 0);
1475 switch (test) {
1476 case 0:
1477 case 1:
1478 if (r != 1) e(0);
1479 break;
1480 case 3:
1481 if (i == 0) {
1482 if (r != -1) e(0);
1483 if (errno != ECONNRESET) e(0);
1484 break;
1486 /* FALLTHROUGH */
1487 case 2:
1488 if (r != -1) e(0);
1489 if (errno != ENOTCONN) e(0);
1491 } else {
1492 r = recv(fd, buf, sizeof(buf), 0);
1494 if (test >= 2) {
1495 if (r != -1) e(0);
1496 if (errno != ENOTCONN) e(0);
1497 } else
1498 if (r != 0) e(0);
1501 exit(errct);
1502 case -1:
1503 e(0);
1507 if (test & 1) {
1508 if ((fl = fcntl(fd, F_GETFL)) == -1) e(0);
1509 if (fcntl(fd, F_SETFL, fl | O_NONBLOCK) != 0) e(0);
1512 r = connect(fd, (struct sockaddr *)&sun, sizeof(sun));
1514 if (test & 1) {
1515 if (r != -1) e(0);
1516 if (errno != EINPROGRESS) e(0);
1518 if (fcntl(fd, F_SETFL, fl) != 0) e(0);
1520 sleep(4);
1521 } else {
1522 if (test >= 2) {
1523 if (r != -1) e(0);
1524 if (errno != ECONNRESET) e(0);
1525 } else
1526 if (r != 0) e(0);
1528 sleep(1);
1532 * If the connect failed, collect the senders and receivers.
1533 * Otherwise, collect just the senders.
1535 for (i = 0; i < __arraycount(pid); i++) {
1536 r = waitpid(pid[i], &status, WNOHANG);
1537 if (r == pid[i]) {
1538 if (test < 2 && (i & 1)) e(0);
1539 if (!WIFEXITED(status)) e(0);
1540 if (WEXITSTATUS(status) != 0) e(0);
1541 } else if (r == 0) {
1542 if (test >= 2 || !(i & 1)) e(0);
1543 } else
1544 e(0);
1547 if (close(fd) != 0) e(0);
1549 /* Wait for, and collect the accepting child. */
1550 if (waitpid(apid, &status, 0) != apid) e(0);
1551 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
1554 * If the connect succeeded, collect the receivers, which will
1555 * terminate once the accepting child closes the accepted socket.
1557 if (test < 2) {
1558 if (waitpid(pid[1], &status, 0) != pid[1]) e(0);
1559 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
1560 if (waitpid(pid[3], &status, 0) != pid[3]) e(0);
1561 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
1564 if (unlink(SOCK_PATH_A) != 0) e(0);
1568 * Test multiple blocked calls getting resumed (or not) upon connect(2) success
1569 * or failure. In particular, ensure that the error code ends up with the
1570 * right call.
1572 static void
1573 test90f(void)
1576 subtest = 6;
1578 /* If a connect succeeds, sends continue but reads block until EOF. */
1579 sub90f(0); /* blocking connect */
1580 sub90f(1); /* non-blocking connect */
1582 /* If a blocking connect fails, the connect call gets the error. */
1583 sub90f(2);
1585 /* If a non-blocking connect fails, the first blocked call gets it. */
1586 sub90f(3);
1590 * Test whether various calls all return the same expected error code.
1592 static void
1593 sub90g(struct sockaddr_un * sun, int err)
1595 int fd;
1597 if ((fd = socket(AF_UNIX, SOCK_SEQPACKET, 0)) < 0) e(0);
1599 if (connect(fd, (struct sockaddr *)sun, sizeof(*sun)) != -1) e(0);
1600 if (errno != err) e(0);
1602 if (close(fd) != 0) e(0);
1604 if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) e(0);
1606 if (sendto(fd, "", 1, 0, (struct sockaddr *)sun, sizeof(*sun)) != -1)
1607 e(0);
1608 if (errno != err) e(0);
1610 if (connect(fd, (struct sockaddr *)sun, sizeof(*sun)) != -1) e(0);
1611 if (errno != err) e(0);
1613 if (close(fd) != 0) e(0);
1617 * Test for error codes thrown by connect(2) and sendto(2) with problematic
1618 * destinations. In particular, we verify that the errors for sendto(2) are
1619 * the same as for connect(2), just like on NetBSD and Linux, even though
1620 * POSIX does not document all of these under sendto(2).
1622 static void
1623 test90g(void)
1625 struct sockaddr_un sun;
1626 int fd;
1628 subtest = 7;
1630 fd = get_bound_socket(SOCK_STREAM, SOCK_PATH_A, &sun);
1632 sub90g(&sun, EPROTOTYPE);
1634 if (listen(fd, 1) != 0) e(0);
1636 sub90g(&sun, EPROTOTYPE);
1638 if (close(fd) != 0) e(0);
1640 sub90g(&sun, ECONNREFUSED);
1642 if (unlink(SOCK_PATH_A) != 0) e(0);
1644 sub90g(&sun, ENOENT);
1648 * Test addresses returned for unbound connection-type sockets by various
1649 * calls.
1651 static void
1652 sub90h(int type)
1654 struct sockaddr_un sun;
1655 socklen_t len;
1656 char buf[1];
1657 int fd, fd2, fd3;
1659 fd = get_bound_socket(type, SOCK_PATH_A, &sun);
1661 if (listen(fd, 5) != 0) e(0);
1663 if ((fd2 = socket(AF_UNIX, type, 0)) < 0) e(0);
1665 if (connect(fd2, (struct sockaddr *)&sun, sizeof(sun)) != 0) e(0);
1667 /* Test for accept(2), which returns an empty address. */
1668 memset(&sun, 0, sizeof(sun));
1669 len = sizeof(sun);
1670 if ((fd3 = accept(fd, (struct sockaddr *)&sun, &len)) < 0) e(0);
1671 check_addr(&sun, len, NULL);
1673 /* Test for recvfrom(2), which ignores the address pointer. */
1674 if (send(fd2, "", 1, 0) != 1) e(0);
1676 memset(&sun, 0, sizeof(sun));
1677 len = sizeof(sun);
1678 if (recvfrom(fd3, buf, sizeof(buf), 0, (struct sockaddr *)&sun,
1679 &len) != 1) e(0);
1680 if (len != 0) e(0);
1681 if (sun.sun_family != 0) e(0);
1682 if (sun.sun_len != 0) e(0);
1684 /* Test for getsockname(2), which returns an empty address. */
1685 memset(&sun, 0, sizeof(sun));
1686 len = sizeof(sun);
1687 if (getsockname(fd2, (struct sockaddr *)&sun, &len) != 0) e(0);
1688 check_addr(&sun, len, NULL);
1690 /* Test for getpeername(2), which returns an empty address. */
1691 memset(&sun, 0, sizeof(sun));
1692 len = sizeof(sun);
1693 if (getpeername(fd3, (struct sockaddr *)&sun, &len) != 0) e(0);
1694 check_addr(&sun, len, NULL);
1696 if (close(fd) != 0) e(0);
1697 if (close(fd2) != 0) e(0);
1698 if (close(fd3) != 0) e(0);
1700 if (unlink(SOCK_PATH_A) != 0) e(0);
1704 * Test addresses returned for unbound sockets by various calls.
1706 static void
1707 test90h(void)
1709 struct sockaddr_un sun;
1710 socklen_t len;
1711 char buf[1];
1712 int fd, fd2;
1714 subtest = 8;
1716 /* Connection-type socket tests. */
1717 sub90h(SOCK_STREAM);
1719 sub90h(SOCK_SEQPACKET);
1721 /* Datagram socket tests. */
1722 fd = get_bound_socket(SOCK_DGRAM, SOCK_PATH_A, &sun);
1724 if ((fd2 = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) e(0);
1726 if (sendto(fd2, "", 1, 0, (struct sockaddr *)&sun, sizeof(sun)) != 1)
1727 e(0);
1730 * Datagram test for recvfrom(2), which returns no address. This is
1731 * the one result in this subtest that is not specified by POSIX and
1732 * (not so coincidentally) is different between NetBSD and Linux.
1733 * MINIX3 happens to follow Linux behavior for now, but this may be
1734 * changed in the future.
1736 memset(&sun, 0, sizeof(sun));
1737 len = sizeof(sun);
1738 if (recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sun,
1739 &len) != 1) e(0);
1740 if (len != 0) e(0);
1741 if (sun.sun_family != 0) e(0);
1742 if (sun.sun_len != 0) e(0);
1744 /* Datagram test for getsockname(2), which returns an empty address. */
1745 memset(&sun, 0, sizeof(sun));
1746 len = sizeof(sun);
1747 if (getsockname(fd2, (struct sockaddr *)&sun, &len) != 0) e(0);
1748 check_addr(&sun, len, NULL);
1750 if (close(fd) != 0) e(0);
1751 if (close(fd2) != 0) e(0);
1753 if (unlink(SOCK_PATH_A) != 0) e(0);
1756 #define MAX_FDS 7
1759 * Send anywhere from zero to MAX_FDS file descriptors onto a socket, possibly
1760 * along with regular data. Return the result of the sendmsg(2) call, with
1761 * errno preserved. Written to be reusable outside this test set.
1763 static int
1764 send_fds(int fd, const char * data, size_t len, int flags,
1765 struct sockaddr * addr, socklen_t addr_len, int * fds, int nfds)
1767 union {
1768 char buf[CMSG_SPACE(MAX_FDS * sizeof(int))];
1769 struct cmsghdr cmsg;
1770 } control;
1771 struct msghdr msg;
1772 struct iovec iov;
1774 assert(nfds >= 0 && nfds <= MAX_FDS);
1776 iov.iov_base = __UNCONST(data);
1777 iov.iov_len = len;
1779 memset(&control.cmsg, 0, sizeof(control.cmsg));
1780 control.cmsg.cmsg_len = CMSG_LEN(nfds * sizeof(int));
1781 control.cmsg.cmsg_level = SOL_SOCKET;
1782 control.cmsg.cmsg_type = SCM_RIGHTS;
1783 memcpy(CMSG_DATA(&control.cmsg), fds, nfds * sizeof(int));
1785 memset(&msg, 0, sizeof(msg));
1786 msg.msg_iov = &iov;
1787 msg.msg_iovlen = 1;
1788 msg.msg_control = &control;
1789 msg.msg_controllen = control.cmsg.cmsg_len;
1790 msg.msg_name = addr;
1791 msg.msg_namelen = addr_len;
1793 return sendmsg(fd, &msg, flags);
1797 * Receive anywhere from zero to up to MAX_FDS file descriptors from a socket,
1798 * possibly along with regular data. The 'nfds' parameter must point to the
1799 * maximum number of file descriptors to be received. Return the result of the
1800 * recvmsg(2) call, with errno preserved. On success, return the received
1801 * flags in 'rflags', the received file descriptors stored in 'fds' and their
1802 * number stored in 'nfds'. Written to be (somewhat) reusable.
1804 static int
1805 recv_fds(int fd, char * buf, size_t size, int flags, int * rflags, int * fds,
1806 int * nfds)
1808 union {
1809 char buf[CMSG_SPACE(MAX_FDS * sizeof(int))];
1810 struct cmsghdr cmsg;
1811 } control;
1812 struct msghdr msg;
1813 struct iovec iov;
1814 size_t len;
1815 int r, rnfds;
1817 assert(*nfds >= 0 && *nfds <= MAX_FDS);
1819 iov.iov_base = buf;
1820 iov.iov_len = size;
1822 memset(&control.cmsg, 0, sizeof(control.cmsg));
1823 control.cmsg.cmsg_len = CMSG_LEN(*nfds * sizeof(int));
1824 control.cmsg.cmsg_level = SOL_SOCKET;
1825 control.cmsg.cmsg_type = SCM_RIGHTS;
1827 memset(&msg, 0, sizeof(msg));
1828 msg.msg_iov = &iov;
1829 msg.msg_iovlen = 1;
1830 msg.msg_control = &control;
1831 msg.msg_controllen = control.cmsg.cmsg_len;
1833 if ((r = recvmsg(fd, &msg, flags)) < 0)
1834 return r;
1836 if (msg.msg_controllen > 0) {
1837 assert(msg.msg_controllen <= sizeof(control));
1838 assert(msg.msg_controllen >= sizeof(control.cmsg));
1839 len = control.cmsg.cmsg_len - CMSG_LEN(0);
1840 assert(len % sizeof(int) == 0);
1841 rnfds = len / sizeof(int);
1842 assert(rnfds <= *nfds);
1844 memcpy(fds, CMSG_DATA(&control.cmsg), rnfds * sizeof(int));
1845 } else
1846 rnfds = 0;
1848 *rflags = msg.msg_flags;
1849 *nfds = rnfds;
1850 return r;
1854 * Generate and send zero or more file descriptors onto a socket, possibly
1855 * along with regular data. Return the result of the sendmsg(2) call, with
1856 * errno preserved. Also return a set of peer FDs for each of the sent file
1857 * descriptors, which should later be used in a call to close_test_fds().
1859 static int
1860 send_test_fds(int fd, const char * data, size_t len, int flags, int * peers,
1861 int nfds)
1863 int i, r, saved_errno, fds[MAX_FDS], pfd[2];
1865 if (nfds > MAX_FDS) e(0);
1867 for (i = 0; i < nfds; i++) {
1868 if (pipe2(pfd, O_NONBLOCK) != 0) e(0);
1870 peers[i] = pfd[0];
1871 fds[i] = pfd[1];
1874 r = send_fds(fd, data, len, flags, NULL, 0, fds, nfds);
1875 saved_errno = errno;
1877 for (i = 0; i < nfds; i++)
1878 if (close(fds[i]) != 0) e(0);
1880 errno = saved_errno;
1881 return r;
1885 * Given an array of peer file descriptors as returned from a call to
1886 * send_test_fds(), test if the original file descriptors have correctly been
1887 * closed, and close all peer file descriptors. The ultimate goal here is to
1888 * detect any possible file descriptor leaks in the UDS service.
1890 static void
1891 close_test_fds(int * peers, int nfds)
1893 char buf[1];
1894 unsigned int i;
1895 int fd;
1897 for (i = 0; i < nfds; i++) {
1898 fd = peers[i];
1900 /* If the other side is still open, we would get EAGAIN. */
1901 if (read(fd, buf, sizeof(buf)) != 0) e(0);
1903 if (close(peers[i]) != 0) e(0);
1908 * Receive and close zero or more file descriptors from a socket, possibly
1909 * along with regular data. Return the result of the recvmsg(2) call, with
1910 * errno preserved.
1912 static int
1913 recv_test_fds(int fd, char * buf, size_t size, int flags, int * rflags,
1914 int * nfds)
1916 int i, r, saved_errno, fds[MAX_FDS];
1918 if (*nfds > MAX_FDS) e(0);
1920 if ((r = recv_fds(fd, buf, size, flags, rflags, fds, nfds)) < 0)
1921 return r;
1922 saved_errno = errno;
1924 for (i = 0; i < *nfds; i++)
1925 if (close(fds[i]) != 0) e(0);
1927 errno = saved_errno;
1928 return r;
1932 * Test receive requests on various socket states and in various forms.
1933 * Following this function requires a very close look at what is in the
1934 * receive queue versus what is being received.
1936 static void
1937 sub90i_recv(int fd, int type, int state, int test, int sub, int sentfds)
1939 struct msghdr msg;
1940 struct iovec iov;
1941 char data[4];
1942 unsigned int i;
1943 int res, err, nfds, rflags;
1945 memset(data, 0, sizeof(data));
1947 if (sub & 2) {
1948 rflags = 0;
1949 nfds = sentfds;
1950 res = recv_test_fds(fd, data, (sub & 1) ? 0 : sizeof(data), 0,
1951 &rflags, &nfds);
1952 if (rflags & MSG_CTRUNC) e(0);
1953 if (nfds != 0 && nfds != sentfds) e(0);
1954 if ((type == SOCK_STREAM) && (rflags & MSG_TRUNC)) e(0);
1955 } else {
1956 iov.iov_base = data;
1957 iov.iov_len = (sub & 1) ? 0 : sizeof(data);
1958 memset(&msg, 0, sizeof(msg));
1959 msg.msg_iov = &iov;
1960 msg.msg_iovlen = 1;
1961 res = recvmsg(fd, &msg, 0);
1962 if (res >= 0)
1963 rflags = msg.msg_flags;
1964 else
1965 rflags = 0;
1966 nfds = 0;
1968 err = errno;
1970 if (res < -1 || res > (int)sizeof(data)) e(0);
1972 if (type == SOCK_STREAM) {
1973 if (sub & 1) {
1975 * Zero-size requests should receive no regular data
1976 * and no control data, even if the tail segment is
1977 * zero-sized and terminated. This policy is in place
1978 * for simplicity reasons.
1980 if (res != 0) e(0);
1981 if (nfds != 0) e(0);
1982 if (rflags & MSG_CTRUNC) e(0);
1985 * Since nothing happened yet, do another, now non-
1986 * zero receive call immediately, and continue as if
1987 * that was the first call.
1989 sub = (sub & ~1) | 2;
1990 nfds = sentfds;
1991 rflags = 0;
1992 res = recv_test_fds(fd, data, sizeof(data), 0, &rflags,
1993 &nfds);
1994 if (rflags & (MSG_TRUNC | MSG_CTRUNC)) e(0);
1995 if (nfds != 0 && nfds != sentfds) e(0);
1996 err = errno;
1997 if (res < -1 || res > (int)sizeof(data)) e(0);
2000 if (state == 0 && !(test & 1) && !(sub & 13)) {
2002 * There are no regular data bytes to be received, and
2003 * the current segment may still be extended (i.e.,
2004 * there is no EOF condition), and we are trying to
2005 * receive at least one data byte. This is the
2006 * SO_RCVLOWAT test.
2008 if (res != -1) e(0);
2009 if (err != EWOULDBLOCK) e(0);
2010 if (test == 4) {
2012 * There are still pending file descriptors but
2013 * we cannot get them, due to the SO_RCVLOWAT
2014 * test. This is proper behavior but somewhat
2015 * annoying, because we want to see if UDS
2016 * forgot to close any file descriptors. So,
2017 * we let it force-close them here.
2019 if (shutdown(fd, SHUT_RD) != 0) e(0);
2020 sub |= 8;
2022 } else {
2023 i = 0;
2024 if (state == 1) {
2025 if (res < 1) e(0);
2026 if (data[i] != 'A') e(0);
2027 i++;
2029 if ((state == 0 && (test & 1)) ||
2030 (state == 1 && (test == 1 || test == 3))) {
2031 if (res < i + 1) e(0);
2032 if (data[i] != 'B') e(0);
2033 i++;
2035 if ((sub & 4) && (state != 1 || test < 4)) {
2036 if (res < i + 1) e(0);
2037 if (data[i] != 'C') e(0);
2038 i++;
2040 if (i != res) e(0);
2041 if (state == 0 && test >= 4) {
2042 if (sub & 2) {
2043 if (nfds != sentfds) e(0);
2044 } else
2045 if (!(rflags & MSG_CTRUNC)) e(0);
2049 if (state == 1 && test >= 4) {
2051 * We just read the first segment, but there is a
2052 * second segment with ancillary data. Read it too.
2054 nfds = sentfds;
2055 rflags = 0;
2056 res = recv_test_fds(fd, data, sizeof(data), 0, &rflags,
2057 &nfds);
2058 if (rflags & (MSG_TRUNC | MSG_CTRUNC)) e(0);
2059 if (nfds != sentfds) e(0); /* untouched on failure */
2060 if (res < -1 || res > (int)sizeof(data)) e(0);
2061 if (test != 5 && !(sub & 12)) {
2062 if (res != -1) e(0);
2063 if (errno != EWOULDBLOCK) e(0);
2064 /* As above. */
2065 if (shutdown(fd, SHUT_RD) != 0) e(0);
2066 sub |= 8;
2067 } else {
2068 if (res != (test == 5) + !!(sub & 4)) e(0);
2069 if (test == 5 && data[0] != 'B') e(0);
2070 if ((sub & 4) && data[res - 1] != 'C') e(0);
2073 } else {
2074 if (res != ((state == 1 || (test & 1)) && !(sub & 1))) e(0);
2075 if (state == 0 && test >= 4) {
2076 if (sub & 2) {
2077 if (nfds != sentfds) e(0);
2078 } else
2079 if (!(rflags & MSG_CTRUNC)) e(0);
2081 if (res > 0 && data[0] != ((state == 1) ? 'A' : 'B')) e(0);
2083 if (state == 1) {
2084 nfds = sentfds;
2085 rflags = 0;
2086 res = recv_test_fds(fd, data, sizeof(data), 0, &rflags,
2087 &nfds);
2088 if (res != (test & 1)) e(0);
2089 if (res > 0 && data[0] != 'B') e(0);
2090 if (nfds != ((test >= 4) ? sentfds : 0)) e(0);
2093 if (sub & 4) {
2094 nfds = sentfds;
2095 rflags = 0;
2096 res = recv_test_fds(fd, data, sizeof(data), 0, &rflags,
2097 &nfds);
2098 if (res != 1) e(0);
2099 if (data[0] != 'C') e(0);
2100 if (nfds != 0) e(0);
2105 * At this point, there is nothing to receive. Depending on
2106 * whether we closed the socket, we expect EOF or EWOULDBLOCK.
2108 res = recv(fd, data, sizeof(data), 0);
2109 if (type == SOCK_DGRAM || !(sub & 8)) {
2110 if (res != -1) e(0);
2111 if (errno != EWOULDBLOCK) e(0);
2112 } else
2113 if (res != 0) e(0);
2117 * Test send requests on various socket states and in various forms.
2119 static void
2120 sub90i_send(int type, int state, int test, int sub)
2122 char *buf;
2123 int r, res, err, fd[2], peers[2], rcvlen;
2125 get_socket_pair(type | SOCK_NONBLOCK, fd);
2128 * State 0: an empty buffer.
2129 * State 1: a non-empty, non-full buffer.
2130 * State 2: a full buffer.
2132 if (state == 2) {
2133 if (type == SOCK_STREAM) {
2134 rcvlen = get_rcvbuf_len(fd[0]);
2136 if ((buf = malloc(rcvlen)) == NULL) e(0);
2138 memset(buf, 'A', rcvlen);
2140 if (send(fd[0], buf, rcvlen, 0) != rcvlen) e(0);
2142 free(buf);
2143 } else {
2144 while ((r = send(fd[0], "A", 1, 0)) == 1);
2145 if (r != -1) e(0);
2146 if (errno !=
2147 ((type == SOCK_SEQPACKET) ? EAGAIN : ENOBUFS))
2148 e(0);
2150 } else if (state == 1)
2151 if (send(fd[0], "A", 1, 0) != 1) e(0);
2154 * Test 0: no data, no control data.
2155 * Test 1: data, no control data.
2156 * Test 2: no data, empty control data.
2157 * Test 3: data, empty control data.
2158 * Test 4: no data, control data with a file descriptor.
2159 * Test 5: data, control data with a file descriptor.
2161 switch (test) {
2162 case 0:
2163 case 1:
2164 res = send(fd[0], "B", test % 2, 0);
2165 err = errno;
2166 break;
2167 case 2:
2168 case 3:
2169 res = send_test_fds(fd[0], "B", test % 2, 0, NULL, 0);
2170 err = errno;
2171 break;
2172 case 4:
2173 case 5:
2174 res = send_test_fds(fd[0], "B", test % 2, 0, peers,
2175 __arraycount(peers));
2176 err = errno;
2177 break;
2178 default:
2179 res = -1;
2180 err = EINVAL;
2181 e(0);
2184 if (res < -1 || res > 1) e(0);
2186 switch (state) {
2187 case 0:
2188 case 1:
2189 if (res != (test % 2)) e(0);
2192 * Subtest bit 0x1: try a zero-size receive first.
2193 * Subtest bit 0x2: try receiving control data.
2194 * Subtest bit 0x4: send an extra segment with no control data.
2195 * Subtest bit 0x8: after completing receives, expect EOF.
2197 if (sub & 4)
2198 if (send(fd[0], "C", 1, 0) != 1) e(0);
2199 if (sub & 8)
2200 if (shutdown(fd[0], SHUT_WR) != 0) e(0);
2203 * Assuming (sub&4), which means there is an extra "C"..
2205 * For stream sockets, we should now receive:
2206 * - state 0:
2207 * - test 0, 2: "C"
2208 * - test 1, 3: "BC"
2209 * - test 4: "C" (w/fds)
2210 * - test 5: "BC" (w/fds)
2211 * - state 1:
2212 * - test 0, 2: "AC"
2213 * - test 1, 3: "ABC"
2214 * - test 4: "A", "C" (w/fds)
2215 * - test 5: "A", "BC" (w/fds)
2217 * For packet sockets, we should now receive:
2218 * - state 1:
2219 * - all tests: "A", followed by..
2220 * - state 0, 1:
2221 * - test 0, 2: "" (no fds), "C"
2222 * - test 1, 3: "B" (no fds), "C"
2223 * - test 4: "" (w/fds), "C"
2224 * - test 5: "B" (w/fds), "C"
2226 sub90i_recv(fd[1], type, state, test, sub,
2227 __arraycount(peers));
2229 break;
2230 case 2:
2232 * Alright, the results are a bit tricky to interpret here,
2233 * because UDS's current strict send admission control prevents
2234 * the receive buffer from being fully utilized. We therefore
2235 * only test the following aspects:
2237 * - if we sent no regular or control data to a stream socket,
2238 * the call should have succeeded (note that the presence of
2239 * empty control data may cause the call to fail);
2240 * - if we sent either regular or control data to a stream
2241 * socket, the call should have failed with EWOULDBLOCK;
2242 * - if the call failed, the error should have been EWOULDBLOCK
2243 * for connection-type sockets and ENOBUFS for connectionless
2244 * sockets.
2246 * Everything else gets a pass; we can't even be sure that for
2247 * packet-oriented sockets we completely filled up the buffer.
2249 if (res == -1) {
2250 if (type == SOCK_STREAM && test == 0) e(0);
2252 if (type != SOCK_DGRAM && err != EWOULDBLOCK) e(0);
2253 if (type == SOCK_DGRAM && err != ENOBUFS) e(0);
2254 } else
2255 if (type == SOCK_STREAM && test != 0) e(0);
2256 break;
2260 * Make sure there are no more in-flight file descriptors now, even
2261 * before closing the socket.
2263 if (res >= 0 && test >= 4)
2264 close_test_fds(peers, __arraycount(peers));
2266 close(fd[0]);
2267 close(fd[1]);
2271 * Test send and receive requests with regular data, control data, both, or
2272 * neither, and test segment boundaries.
2274 static void
2275 test90i(void)
2277 int state, test, sub;
2279 subtest = 9;
2281 for (state = 0; state < 3; state++) {
2282 for (test = 0; test < 6; test++) {
2283 for (sub = 0; sub < ((state < 2) ? 16 : 1); sub++) {
2284 sub90i_send(SOCK_STREAM, state, test, sub);
2286 sub90i_send(SOCK_SEQPACKET, state, test, sub);
2288 sub90i_send(SOCK_DGRAM, state, test, sub);
2295 * Test segmentation of file descriptor transfer on a particular socket type.
2297 static void
2298 sub90j(int type)
2300 char path[PATH_MAX], buf[2];
2301 int i, fd[2], out[7], in[7], rflags, nfds;
2302 ssize_t len;
2304 get_socket_pair(type, fd);
2306 for (i = 0; i < __arraycount(out); i++) {
2307 snprintf(path, sizeof(path), "file%d", i);
2308 out[i] = open(path, O_RDWR | O_CREAT | O_EXCL | O_TRUNC, 0644);
2309 if (out[i] < 0) e(0);
2310 if (write(out[i], path, strlen(path)) != strlen(path)) e(0);
2311 if (lseek(out[i], 0, SEEK_SET) != 0) e(0);
2314 if (send_fds(fd[1], "A", 1, 0, NULL, 0, &out[0], 1) != 1) e(0);
2315 if (send_fds(fd[1], "B", 1, 0, NULL, 0, &out[1], 3) != 1) e(0);
2316 if (send_fds(fd[1], "C", 1, 0, NULL, 0, &out[4], 2) != 1) e(0);
2318 nfds = 2;
2319 if (recv_fds(fd[0], buf, sizeof(buf), 0, &rflags, &in[0], &nfds) != 1)
2320 e(0);
2321 if (buf[0] != 'A') e(0);
2322 if (rflags != 0) e(0);
2323 if (nfds != 1) e(0);
2325 nfds = 5;
2326 if (recv_fds(fd[0], buf, sizeof(buf), 0, &rflags, &in[1], &nfds) != 1)
2327 e(0);
2328 if (buf[0] != 'B') e(0);
2329 if (rflags != 0) e(0);
2330 if (nfds != 3) e(0);
2332 if (send_fds(fd[1], "D", 1, 0, NULL, 0, &out[6], 1) != 1) e(0);
2334 nfds = 2;
2335 if (recv_fds(fd[0], buf, sizeof(buf), 0, &rflags, &in[4], &nfds) != 1)
2336 e(0);
2337 if (buf[0] != 'C') e(0);
2338 if (rflags != 0) e(0);
2339 if (nfds != 2) e(0);
2341 nfds = 2;
2342 if (recv_fds(fd[0], buf, sizeof(buf), 0, &rflags, &in[6], &nfds) != 1)
2343 e(0);
2344 if (buf[0] != 'D') e(0);
2345 if (rflags != 0) e(0);
2346 if (nfds != 1) e(0);
2348 for (i = 0; i < __arraycount(in); i++) {
2349 len = read(in[i], path, sizeof(path));
2350 if (len < 5 || len > 7) e(0);
2351 path[len] = '\0';
2352 if (strncmp(path, "file", 4) != 0) e(0);
2353 if (atoi(&path[4]) != i) e(0);
2354 if (unlink(path) != 0) e(0);
2355 if (close(in[i]) != 0) e(0);
2358 for (i = 0; i < __arraycount(out); i++)
2359 if (close(out[i]) != 0) e(0);
2362 * While we're here, see if UDS properly closes any remaining in-flight
2363 * file descriptors when the socket is closed.
2365 if (send_test_fds(fd[1], "E", 1, 0, out, 7) != 1) e(0);
2367 close(fd[0]);
2368 close(fd[1]);
2370 close_test_fds(out, 7);
2374 * Test segmentation of file descriptor transfer. That is, there are multiple
2375 * in-flight file descriptors, they must each be associated with their
2376 * respective segments.
2378 static void
2379 test90j(void)
2382 subtest = 10;
2384 sub90j(SOCK_STREAM);
2386 sub90j(SOCK_SEQPACKET);
2388 sub90j(SOCK_DGRAM);
2392 * Test whether we can deadlock UDS by making it close the last reference to
2393 * an in-flight file descriptor for a UDS socket. Currently we allow VFS/UDS
2394 * to get away with throwing EDEADLK as a sledgehammer approach to preventing
2395 * problems with in-flight UDS sockets.
2397 static void
2398 test90k(void)
2400 int r, fd[2], fd2;
2402 subtest = 11;
2404 get_socket_pair(SOCK_STREAM, fd);
2406 if ((fd2 = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) e(0);
2408 if ((r = send_fds(fd[0], "X", 1, 0, NULL, 0, &fd2, 1)) != 1) {
2409 if (r != -1) e(0);
2410 if (errno != EDEADLK) e(0); /* whew */
2413 if (close(fd2) != 0) e(0);
2414 if (close(fd[0]) != 0) e(0);
2415 if (close(fd[1]) != 0) e(0); /* boom */
2419 * Test whether we can make UDS run out of file descriptors by transferring a
2420 * UDS socket over itself and then closing all other references while it is
2421 * in-flight. Currently we allow VFS/UDS to get away with throwing EDEADLK as
2422 * a sledgehammer approach to preventing problems with in-flight UDS sockets.
2424 static void
2425 test90l(void)
2427 struct sockaddr_un sun;
2428 int i, r, fd, fd2;
2430 subtest = 12;
2432 fd = get_bound_socket(SOCK_DGRAM, SOCK_PATH_A, &sun);
2434 for (i = 0; i < OPEN_MAX + 1; i++) {
2435 if ((fd2 = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) e(0);
2437 if ((r = send_fds(fd2, "X", 1, 0, (struct sockaddr *)&sun,
2438 sizeof(sun), &fd2, 1)) != 1) {
2439 if (r != -1) e(0);
2440 if (errno != EDEADLK) e(0); /* whew */
2443 if (close(fd2) != 0) e(0); /* have fun in limbo.. */
2446 if (close(fd) != 0) e(0);
2447 if (unlink(SOCK_PATH_A) != 0) e(0);
2451 * Receive with credentials.
2453 static int
2454 recv_creds(int fd, char * buf, size_t size, int flags, int * rflags,
2455 struct sockcred * sc, socklen_t * sc_len)
2457 union {
2458 char buf[CMSG_SPACE(SOCKCREDSIZE(NGROUPS_MAX))];
2459 struct cmsghdr cmsg;
2460 } control;
2461 struct msghdr msg;
2462 struct iovec iov;
2463 size_t len;
2464 int r;
2466 iov.iov_base = buf;
2467 iov.iov_len = size;
2469 memset(&control.cmsg, 0, sizeof(control.cmsg));
2470 control.cmsg.cmsg_len = CMSG_LEN(SOCKCREDSIZE(NGROUPS_MAX));
2471 control.cmsg.cmsg_level = SOL_SOCKET;
2472 control.cmsg.cmsg_type = SCM_RIGHTS;
2474 memset(&msg, 0, sizeof(msg));
2475 msg.msg_iov = &iov;
2476 msg.msg_iovlen = 1;
2477 msg.msg_control = &control;
2478 msg.msg_controllen = control.cmsg.cmsg_len;
2480 if ((r = recvmsg(fd, &msg, flags)) < 0)
2481 return r;
2483 if (msg.msg_controllen > 0) {
2484 assert(msg.msg_controllen <= sizeof(control));
2485 assert(msg.msg_controllen >= sizeof(control.cmsg));
2486 assert(control.cmsg.cmsg_len <= msg.msg_controllen);
2487 len = control.cmsg.cmsg_len - CMSG_LEN(0);
2488 assert(len >= sizeof(struct sockcred));
2489 assert(len <= SOCKCREDSIZE(NGROUPS_MAX));
2490 if (*sc_len > len)
2491 *sc_len = len;
2492 memcpy(sc, CMSG_DATA(&control.cmsg), *sc_len);
2493 } else
2494 *sc_len = 0;
2496 *rflags = msg.msg_flags;
2497 return r;
2501 * Test basic credentials passing on connection-oriented sockets.
2503 static void
2504 sub90m(int type)
2506 struct sockaddr_un sun;
2507 struct sockcred sc;
2508 struct msghdr msg;
2509 struct iovec iov;
2510 socklen_t len;
2511 char buf[1];
2512 int fd, fd2, fd3, val, rflags;
2514 fd = get_bound_socket(type, SOCK_PATH_A, &sun);
2516 val = 1;
2517 if (setsockopt(fd, 0, LOCAL_CREDS, &val, sizeof(val)) != 0) e(0);
2519 if (listen(fd, 1) != 0) e(0);
2521 if ((fd2 = socket(AF_UNIX, type | SOCK_NONBLOCK, 0)) < 0) e(0);
2523 if (connect(fd2, (struct sockaddr *)&sun, sizeof(sun)) != 0) e(0);
2525 len = sizeof(sun);
2526 if ((fd3 = accept(fd, (struct sockaddr *)&sun, &len)) < 0) e(0);
2528 if (send(fd2, "A", 1, 0) != 1) e(0);
2529 if (send(fd2, "B", 1, 0) != 1) e(0);
2531 len = sizeof(sc);
2532 if (recv_creds(fd3, buf, sizeof(buf), 0, &rflags, &sc, &len) != 1)
2533 e(0);
2534 if (buf[0] != 'A') e(0);
2535 if (rflags != 0) e(0);
2536 if (len != sizeof(sc)) e(0);
2537 if (sc.sc_uid != getuid()) e(0);
2538 if (sc.sc_euid != geteuid()) e(0);
2540 len = sizeof(sc);
2541 if (recv_creds(fd3, buf, sizeof(buf), 0, &rflags, &sc, &len) != 1)
2542 e(0);
2543 if (buf[0] != 'B') e(0);
2544 if (rflags != 0) e(0);
2545 if (len != 0) e(0);
2547 if (send(fd3, "C", 1, 0) != 1) e(0);
2549 val = 1;
2550 if (setsockopt(fd2, 0, LOCAL_CREDS, &val, sizeof(val)) != 0) e(0);
2552 if (send(fd3, "D", 1, 0) != 1) e(0);
2554 val = 1;
2555 if (setsockopt(fd2, 0, LOCAL_CREDS, &val, sizeof(val)) != 0) e(0);
2557 if (send(fd3, "E", 1, 0) != 1) e(0);
2559 len = sizeof(sc);
2560 if (recv_creds(fd2, buf, sizeof(buf), 0, &rflags, &sc, &len) != 1)
2561 e(0);
2562 if (buf[0] != 'C') e(0);
2563 if (rflags != 0) e(0);
2564 if (len != 0) e(0);
2566 len = sizeof(sc);
2567 if (recv_creds(fd2, buf, sizeof(buf), 0, &rflags, &sc, &len) != 1)
2568 e(0);
2569 if (buf[0] != 'D') e(0);
2570 if (rflags != 0) e(0);
2571 if (len != sizeof(sc)) e(0);
2572 if (sc.sc_uid != getuid()) e(0);
2573 if (sc.sc_euid != geteuid()) e(0);
2575 memset(&msg, 0, sizeof(msg));
2576 iov.iov_base = buf;
2577 iov.iov_len = sizeof(buf);
2578 msg.msg_iov = &iov;
2579 msg.msg_iovlen = 1;
2580 if (recvmsg(fd2, &msg, 0) != 1) e(0);
2581 if (buf[0] != 'E') e(0);
2582 if (msg.msg_flags != MSG_CTRUNC) e(0);
2584 if (close(fd2) != 0) e(0);
2585 if (close(fd3) != 0) e(0);
2587 val = 0;
2588 if (setsockopt(fd, 0, LOCAL_CREDS, &val, sizeof(val)) != 0) e(0);
2590 if ((fd2 = socket(AF_UNIX, type, 0)) < 0) e(0);
2592 if (connect(fd2, (struct sockaddr *)&sun, sizeof(sun)) != 0) e(0);
2594 len = sizeof(sun);
2595 if ((fd3 = accept(fd, (struct sockaddr *)&sun, &len)) < 0) e(0);
2597 if (send(fd2, "F", 1, 0) != 1) e(0);
2599 len = sizeof(sc);
2600 if (recv_creds(fd3, buf, sizeof(buf), 0, &rflags, &sc, &len) != 1)
2601 e(0);
2602 if (buf[0] != 'F') e(0);
2603 if (rflags != 0) e(0);
2604 if (len != 0) e(0);
2606 if (close(fd) != 0) e(0);
2607 if (close(fd2) != 0) e(0);
2608 if (close(fd3) != 0) e(0);
2610 if (unlink(SOCK_PATH_A) != 0) e(0);
2614 * A few tests for credentials passing that matter to some applications:
2615 * the credentials passing setting is inherited by accepted connections from
2616 * their listening socket, and, credentials are passed only once on a
2617 * connection-oriented socket.
2619 static void
2620 test90m(void)
2622 struct sockcred sc;
2623 socklen_t len;
2624 char buf[1];
2625 int fd[2], val, rflags;
2627 subtest = 13;
2629 sub90m(SOCK_STREAM);
2631 sub90m(SOCK_SEQPACKET);
2633 get_socket_pair(SOCK_DGRAM, fd);
2635 val = 1;
2636 if (setsockopt(fd[0], 0, LOCAL_CREDS, &val, sizeof(val)) != 0) e(0);
2638 if (send(fd[1], "A", 1, 0) != 1) e(0);
2639 if (send(fd[0], "B", 1, 0) != 1) e(0);
2640 if (send(fd[1], "C", 1, 0) != 1) e(0);
2642 len = sizeof(sc);
2643 if (recv_creds(fd[0], buf, sizeof(buf), 0, &rflags, &sc, &len) != 1)
2644 e(0);
2645 if (buf[0] != 'A') e(0);
2646 if (rflags != 0) e(0);
2647 if (len != sizeof(sc)) e(0);
2648 if (sc.sc_uid != getuid()) e(0);
2649 if (sc.sc_euid != geteuid()) e(0);
2651 len = sizeof(sc);
2652 if (recv_creds(fd[1], buf, sizeof(buf), 0, &rflags, &sc, &len) != 1)
2653 e(0);
2654 if (buf[0] != 'B') e(0);
2655 if (rflags != 0) e(0);
2656 if (len != 0) e(0);
2658 len = sizeof(sc);
2659 if (recv_creds(fd[0], buf, sizeof(buf), 0, &rflags, &sc, &len) != 1)
2660 e(0);
2661 if (buf[0] != 'C') e(0);
2662 if (rflags != 0) e(0);
2663 if (len != sizeof(sc)) e(0);
2664 if (sc.sc_uid != getuid()) e(0);
2665 if (sc.sc_euid != geteuid()) e(0);
2667 if (close(fd[0]) != 0) e(0);
2668 if (close(fd[1]) != 0) e(0);
2672 * Test whether MSG_CMSG_CLOEXEC is honored when copying in file descriptors.
2673 * We do not bother to test with execve(2w); obtaining the FD flags suffices.
2675 static void
2676 test90n(void)
2678 char buf[1];
2679 int i, fd[2], sfd, rfd, fl, rflags, nfds;
2681 subtest = 14;
2683 get_socket_pair(SOCK_STREAM, fd);
2685 if ((sfd = open("/dev/null", O_RDONLY)) < 0) e(0);
2687 if (send_fds(fd[0], "A", 1, 0, NULL, 0, &sfd, 1) != 1) e(0);
2688 if (send_fds(fd[0], "B", 1, 0, NULL, 0, &sfd, 1) != 1) e(0);
2690 if ((fl = fcntl(sfd, F_GETFD, 0)) < 0) e(0);
2691 if (fcntl(sfd, F_SETFD, fl | FD_CLOEXEC) != 0) e(0);
2693 if (send_fds(fd[0], "C", 1, 0, NULL, 0, &sfd, 1) != 1) e(0);
2694 if (send_fds(fd[0], "D", 1, 0, NULL, 0, &sfd, 1) != 1) e(0);
2696 for (i = 0; i < 4; i++) {
2697 fl = (i & 1) ? MSG_CMSG_CLOEXEC : 0;
2698 nfds = 1;
2699 if (recv_fds(fd[1], buf, sizeof(buf), fl, &rflags, &rfd,
2700 &nfds) != 1) e(0);
2701 if (buf[0] != 'A' + i) e(0);
2702 if (rflags != 0) e(0);
2703 if (nfds != 1) e(0);
2705 if ((fl = fcntl(rfd, F_GETFD, 0)) < 0) e(0);
2706 if (!!(fl & FD_CLOEXEC) != (i & 1)) e(0);
2708 if (close(rfd) != 0) e(0);
2711 if (close(sfd) != 0) e(0);
2712 if (close(fd[0]) != 0) e(0);
2713 if (close(fd[1]) != 0) e(0);
2717 * Test failures sending and receiving sets of file descriptors.
2719 static void
2720 sub90o(int type)
2722 static int ofd[OPEN_MAX];
2723 char buf[1];
2724 int i, fd[2], sfd[2], rfd[2], rflags, nfds;
2726 get_socket_pair(type, fd);
2728 if ((sfd[0] = open("/dev/null", O_RDONLY)) < 0) e(0);
2729 sfd[1] = -1;
2731 if (send_fds(fd[0], "A", 1, 0, NULL, 0, &sfd[1], 1) != -1) e(0);
2732 if (errno != EBADF) e(0);
2733 if (send_fds(fd[0], "B", 1, 0, NULL, 0, &sfd[0], 2) != -1) e(0);
2734 if (errno != EBADF) e(0);
2735 if ((sfd[1] = dup(sfd[0])) < 0) e(0);
2736 if (send_fds(fd[0], "C", 1, 0, NULL, 0, &sfd[0], 2) != 1) e(0);
2738 for (i = 0; i < __arraycount(ofd); i++) {
2739 if ((ofd[i] = dup(sfd[0])) < 0) {
2740 /* Either will do. */
2741 if (errno != EMFILE && errno != ENFILE) e(0);
2742 break;
2746 nfds = 2;
2747 if (recv_fds(fd[1], buf, sizeof(buf), 0, &rflags, rfd, &nfds) != -1)
2748 e(0);
2749 if (errno != ENFILE && errno != EMFILE) e(0);
2751 if (close(sfd[1]) != 0) e(0);
2753 nfds = 2;
2754 if (recv_fds(fd[1], buf, sizeof(buf), 0, &rflags, rfd, &nfds) != -1)
2755 e(0);
2756 if (errno != ENFILE && errno != EMFILE) e(0);
2758 if (close(sfd[0]) != 0) e(0);
2760 nfds = 2;
2761 if (recv_fds(fd[1], buf, sizeof(buf), 0, &rflags, rfd, &nfds) != 1)
2762 e(0);
2763 if (buf[0] != 'C') e(0);
2764 if (rflags != 0) e(0);
2765 if (nfds != 2) e(0);
2767 if (close(rfd[1]) != 0) e(0);
2768 if (close(rfd[0]) != 0) e(0);
2769 while (i-- > 0)
2770 if (close(ofd[i]) != 0) e(0);
2771 if (close(fd[1]) != 0) e(0);
2772 if (close(fd[0]) != 0) e(0);
2776 * Test failures sending and receiving sets of file descriptors.
2778 static void
2779 test90o(void)
2781 const int types[] = { SOCK_STREAM, SOCK_SEQPACKET, SOCK_DGRAM };
2782 int i;
2784 subtest = 15;
2786 for (i = 0; i < OPEN_MAX + 1; i++)
2787 sub90o(types[i % __arraycount(types)]);
2791 * Test socket reuse for a particular socket type.
2793 static void
2794 sub90p(int type)
2796 struct sockaddr_un sunA, sunB, sunC;
2797 socklen_t len;
2798 char buf[1];
2799 uid_t euid;
2800 gid_t egid;
2801 int fd, fd2, fd3, val;
2803 if ((fd = socket(AF_UNIX, type | SOCK_NONBLOCK, 0)) < 0) e(0);
2804 /* Unconnected. */
2806 if (getpeereid(fd, &euid, &egid) != -1) e(0);
2807 if (errno != ENOTCONN) e(0);
2809 fd2 = get_bound_socket(type, SOCK_PATH_A, &sunA);
2811 val = 1;
2812 if (setsockopt(fd2, 0, LOCAL_CONNWAIT, &val, sizeof(val)) != 0) e(0);
2814 if (listen(fd2, 5) != 0) e(0);
2816 if (connect(fd, (struct sockaddr *)&sunA, sizeof(sunA)) != -1) e(0);
2817 if (errno != EINPROGRESS) e(0);
2818 /* Connecting. */
2820 if (getpeereid(fd, &euid, &egid) != -1) e(0);
2821 if (errno != ENOTCONN) e(0);
2823 len = sizeof(sunB);
2824 if ((fd3 = accept(fd2, (struct sockaddr *)&sunB, &len)) < 0) e(0);
2825 /* Connected. */
2827 len = sizeof(sunC);
2828 if (getpeername(fd, (struct sockaddr *)&sunC, &len) != 0) e(0);
2829 check_addr(&sunC, len, SOCK_PATH_A);
2831 if (getpeereid(fd, &euid, &egid) != 0) e(0);
2832 if (euid == -1 || egid == -1) e(0);
2834 if (getpeereid(fd3, &euid, &egid) != 0) e(0);
2835 if (euid == -1 || egid == -1) e(0);
2837 if (send(fd3, "A", 1, 0) != 1) e(0);
2838 if (send(fd3, "B", 1, 0) != 1) e(0);
2839 if (send(fd3, "C", 1, 0) != 1) e(0);
2841 if (close(fd3) != 0) e(0);
2842 /* Disconnected. */
2844 if (getpeereid(fd, &euid, &egid) != -1) e(0);
2845 if (errno != ENOTCONN) e(0);
2847 if (close(fd2) != 0) e(0);
2848 fd2 = get_bound_socket(type, SOCK_PATH_B, &sunA);
2850 if (listen(fd2, 5) != 0) e(0);
2852 val = 1;
2853 if (setsockopt(fd, 0, LOCAL_CONNWAIT, &val, sizeof(val)) != 0) e(0);
2855 if (connect(fd, (struct sockaddr *)&sunA, sizeof(sunA)) != -1) e(0);
2856 if (errno != EINPROGRESS) e(0);
2857 /* Connecting. */
2859 if (getpeereid(fd, &euid, &egid) != -1) e(0);
2860 if (errno != ENOTCONN) e(0);
2862 if (recv(fd, buf, 1, 0) != 1) e(0);
2863 if (buf[0] != 'A') e(0);
2865 len = sizeof(sunB);
2866 if ((fd3 = accept(fd2, (struct sockaddr *)&sunB, &len)) < 0) e(0);
2867 /* Connected. */
2869 if (send(fd3, "D", 1, 0) != 1) e(0);
2870 if (send(fd3, "E", 1, 0) != 1) e(0);
2872 len = sizeof(sunC);
2873 if (getpeername(fd, (struct sockaddr *)&sunC, &len) != 0) e(0);
2874 check_addr(&sunC, len, SOCK_PATH_B);
2876 if (getpeereid(fd, &euid, &egid) != 0) e(0);
2877 if (euid == -1 || egid == -1) e(0);
2879 if (close(fd2) != 0) e(0);
2880 if (unlink(SOCK_PATH_B) != 0) e(0);
2882 if (close(fd3) != 0) e(0);
2883 /* Disconnected. */
2885 if (connect(fd, (struct sockaddr *)&sunA, sizeof(sunA)) != -1) e(0);
2886 if (errno != ENOENT) e(0);
2887 /* Unconnected. */
2889 if (getpeereid(fd, &euid, &egid) != -1) e(0);
2890 if (errno != ENOTCONN) e(0);
2892 if (recv(fd, buf, 1, 0) != 1) e(0);
2893 if (buf[0] != 'B') e(0);
2895 if (unlink(SOCK_PATH_A) != 0) e(0);
2897 if (bind(fd, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
2899 if (recv(fd, buf, 1, 0) != 1) e(0);
2900 if (buf[0] != 'C') e(0);
2902 val = 0;
2903 if (setsockopt(fd, 0, LOCAL_CONNWAIT, &val, sizeof(val)) != 0) e(0);
2905 if (listen(fd, 1) != 0) e(0);
2906 /* Listening. */
2908 if (recv(fd, buf, 1, 0) != 1) e(0);
2909 if (buf[0] != 'D') e(0);
2911 if ((fd2 = socket(AF_UNIX, type, 0)) < 0) e(0);
2913 if (connect(fd2, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
2915 len = sizeof(sunC);
2916 if ((fd3 = accept(fd, (struct sockaddr *)&sunC, &len)) < 0) e(0);
2918 if (send(fd2, "F", 1, 0) != 1) e(0);
2920 if (recv(fd3, buf, 1, 0) != 1) e(0);
2921 if (buf[0] != 'F') e(0);
2923 if (recv(fd, buf, 1, 0) != 1) e(0);
2924 if (buf[0] != 'E') e(0);
2926 if (recv(fd, buf, 1, 0) != -1) e(0);
2927 if (errno != ENOTCONN) e(0);
2929 /* It should be possible to obtain peer credentials now. */
2930 if (getpeereid(fd2, &euid, &egid) != 0) e(0);
2931 if (euid == -1 || egid == -1) e(0);
2933 if (getpeereid(fd3, &euid, &egid) != 0) e(0);
2934 if (euid == -1 || egid == -1) e(0);
2936 if (close(fd3) != 0) e(0);
2937 if (close(fd2) != 0) e(0);
2939 if (close(fd) != 0) e(0);
2940 /* Closed. */
2942 if (unlink(SOCK_PATH_B) != 0) e(0);
2944 if ((fd = socket(AF_UNIX, type, 0)) < 0) e(0);
2945 /* Unconnected. */
2947 fd2 = get_bound_socket(type, SOCK_PATH_A, &sunA);
2949 if (listen(fd2, 5) != 0) e(0);
2951 if (connect(fd, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
2952 /* Connected. */
2954 len = sizeof(sunB);
2955 if ((fd3 = accept(fd2, (struct sockaddr *)&sunB, &len)) < 0) e(0);
2957 if (close(fd2) != 0) e(0);
2959 memset(&sunB, 0, sizeof(sunB));
2960 sunB.sun_family = AF_UNIX;
2961 strlcpy(sunB.sun_path, SOCK_PATH_B, sizeof(sunB.sun_path));
2963 if (bind(fd, (struct sockaddr *)&sunB, sizeof(sunB)) != 0) e(0);
2965 if (close(fd3) != 0) e(0);
2966 /* Disconnected. */
2968 if (listen(fd, 1) != 0) e(0);
2969 /* Listening. */
2971 if ((fd2 = socket(AF_UNIX, type, 0)) < 0) e(0);
2973 if (connect(fd2, (struct sockaddr *)&sunB, sizeof(sunB)) != 0) e(0);
2975 len = sizeof(sunC);
2976 if ((fd3 = accept(fd, (struct sockaddr *)&sunC, &len)) < 0) e(0);
2978 /* It should NOT be possible to obtain peer credentials now. */
2979 if (getpeereid(fd2, &euid, &egid) != -1) e(0);
2980 if (errno != EINVAL) e(0);
2982 if (getpeereid(fd3, &euid, &egid) != 0) e(0);
2983 if (euid == -1 || egid == -1) e(0);
2985 if (close(fd3) != 0) e(0);
2986 if (close(fd2) != 0) e(0);
2988 if (close(fd) != 0) e(0);
2989 /* Closed. */
2991 if (unlink(SOCK_PATH_A) != 0) e(0);
2992 if (unlink(SOCK_PATH_B) != 0) e(0);
2996 * Test socket reuse, receiving left-overs in the receive buffer, and the
2997 * (in)ability to obtain peer credentials.
2999 static void
3000 test90p(void)
3003 subtest = 16;
3005 sub90p(SOCK_STREAM);
3007 sub90p(SOCK_SEQPACKET);
3011 * Test state changes and errors related to connected datagram sockets.
3013 static void
3014 test90q(void)
3016 struct sockaddr_un sunA, sunB, sunC, sunD;
3017 socklen_t len;
3018 char buf[1];
3019 int fd, fd2, fd3, val;
3021 subtest = 17;
3024 * Sending a datagram to a datagram socket connected elsewhere should
3025 * fail explicitly (specifically, EPERM).
3027 fd = get_bound_socket(SOCK_DGRAM, SOCK_PATH_A, &sunA);
3028 fd2 = get_bound_socket(SOCK_DGRAM, SOCK_PATH_B, &sunB);
3029 fd3 = get_bound_socket(SOCK_DGRAM, SOCK_PATH_C, &sunC);
3031 if (connect(fd2, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
3033 if (sendto(fd3, "A", 1, 0, (struct sockaddr *)&sunB,
3034 sizeof(sunB)) != -1) e(0);
3035 if (errno != EPERM) e(0);
3037 /* Similarly, connecting to such a socket should fail. */
3038 if (connect(fd3, (struct sockaddr *)&sunB, sizeof(sunB)) != -1) e(0);
3039 if (errno != EPERM) e(0);
3041 if (send(fd2, "B", 1, 0) != 1) e(0);
3043 if (recv(fd, buf, 1, 0) != 1) e(0);
3044 if (buf[0] != 'B') e(0);
3046 /* Reconnection of a socket's target should result in ECONNRESET. */
3047 if (connect(fd, (struct sockaddr *)&sunC, sizeof(sunC)) != 0) e(0);
3049 len = sizeof(val);
3050 if (getsockopt(fd2, SOL_SOCKET, SO_ERROR, &val, &len) != 0) e(0);
3051 if (val != ECONNRESET) e(0);
3053 if (send(fd2, "C", 1, 0) != -1) e(0);
3054 if (errno != EDESTADDRREQ) e(0);
3056 if (send(fd, "D", 1, 0) != 1) e(0);
3058 len = sizeof(sunD);
3059 if (recvfrom(fd3, buf, 1, 0, (struct sockaddr *)&sunD, &len) != 1)
3060 e(0);
3061 if (buf[0] != 'D') e(0);
3062 check_addr(&sunD, len, SOCK_PATH_A);
3064 if (connect(fd2, (struct sockaddr *)&sunC, sizeof(sunC)) != 0) e(0);
3066 if (connect(fd3, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
3068 memset(&sunD, 0, sizeof(sunD));
3069 sunD.sun_family = AF_UNIX;
3070 strlcpy(sunD.sun_path, SOCK_PATH_D, sizeof(sunD.sun_path));
3072 /* A failed reconnection attempt should not break the previous one. */
3073 if (connect(fd3, (struct sockaddr *)&sunD, sizeof(sunD)) != -1) e(0);
3074 if (errno != ENOENT) e(0);
3076 /* The destination address should be ignored here. */
3077 if (sendto(fd3, "E", 1, 0, (struct sockaddr *)&sunB,
3078 sizeof(sunB)) != 1) e(0);
3080 if (recv(fd2, buf, 1, 0) != -1) e(0);
3081 if (errno != ECONNRESET) e(0);
3083 if (recv(fd, buf, 1, 0) != 1) e(0);
3084 if (buf[0] != 'E') e(0);
3086 if (close(fd3) != 0) e(0);
3088 len = sizeof(val);
3089 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &val, &len) != 0) e(0);
3090 if (val != ECONNRESET) e(0);
3092 if (close(fd2) != 0) e(0);
3094 len = sizeof(val);
3095 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &val, &len) != 0) e(0);
3096 if (val != 0) e(0);
3098 if (close(fd) != 0) e(0);
3100 if (unlink(SOCK_PATH_A) != 0) e(0);
3101 if (unlink(SOCK_PATH_B) != 0) e(0);
3102 if (unlink(SOCK_PATH_C) != 0) e(0);
3105 * Finally, test unconnecting sockets.
3107 fd = get_bound_socket(SOCK_DGRAM, SOCK_PATH_A, &sunA);
3108 fd2 = get_bound_socket(SOCK_DGRAM, SOCK_PATH_B, &sunB);
3110 if (connect(fd, (struct sockaddr *)&sunB, sizeof(sunB)) != 0) e(0);
3112 if (connect(fd2, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
3114 if (sendto(fd2, "F", 1, 0, NULL, 0) != 1) e(0);
3116 if (recv(fd, buf, 1, 0) != 1) e(0);
3117 if (buf[0] != 'F') e(0);
3119 memset(&sunC, 0, sizeof(sunC));
3120 sunC.sun_family = AF_UNSPEC;
3121 if (connect(fd2, (struct sockaddr *)&sunC, sizeof(sunC)) != 0) e(0);
3123 len = sizeof(val);
3124 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &val, &len) != 0) e(0);
3125 if (val != 0) e(0);
3127 if (send(fd, "G", 1, 0) != 1) e(0);
3129 if (sendto(fd2, "H", 1, 0, NULL, 0) != -1) e(0);
3130 if (errno != EDESTADDRREQ) e(0);
3132 if (sendto(fd2, "I", 1, 0, (struct sockaddr *)&sunA, sizeof(sunA)) != 1)
3133 e(0);
3135 if (connect(fd2, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
3137 if (sendto(fd2, "J", 1, 0, NULL, 0) != 1) e(0);
3139 if (recv(fd, buf, 1, 0) != 1) e(0);
3140 if (buf[0] != 'I') e(0);
3142 if (recv(fd, buf, 1, 0) != 1) e(0);
3143 if (buf[0] != 'J') e(0);
3145 if (recv(fd2, buf, 1, 0) != 1) e(0);
3146 if (buf[0] != 'G') e(0);
3148 if (close(fd) != 0) e(0);
3149 if (close(fd2) != 0) e(0);
3151 if (unlink(SOCK_PATH_A) != 0) e(0);
3152 if (unlink(SOCK_PATH_B) != 0) e(0);
3156 * Test socket file name reuse.
3158 static void
3159 test90r(void)
3161 struct sockaddr_un sun;
3162 socklen_t len;
3163 int fd, fd2, fd3, fd4;
3165 subtest = 18;
3167 fd = get_bound_socket(SOCK_STREAM | SOCK_NONBLOCK, SOCK_PATH_A, &sun);
3169 if (rename(SOCK_PATH_A, SOCK_PATH_B) != 0) e(0);
3171 if ((fd3 = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) e(0);
3173 if (connect(fd3, (struct sockaddr *)&sun, sizeof(sun)) != -1) e(0);
3174 if (errno != ENOENT) e(0);
3176 if (listen(fd, 1) != 0) e(0);
3178 len = sizeof(sun);
3179 if (getsockname(fd, (struct sockaddr *)&sun, &len) != 0) e(0);
3180 check_addr(&sun, len, SOCK_PATH_A);
3182 fd2 = get_bound_socket(SOCK_STREAM | SOCK_NONBLOCK, SOCK_PATH_A, &sun);
3184 if (listen(fd2, 1) != 0) e(0);
3186 len = sizeof(sun);
3187 if (getsockname(fd2, (struct sockaddr *)&sun, &len) != 0) e(0);
3188 check_addr(&sun, len, SOCK_PATH_A);
3190 len = sizeof(sun);
3191 if (getsockname(fd, (struct sockaddr *)&sun, &len) != 0) e(0);
3192 check_addr(&sun, len, SOCK_PATH_A);
3194 memset(&sun, 0, sizeof(sun));
3195 sun.sun_family = AF_UNIX;
3196 strlcpy(sun.sun_path, SOCK_PATH_B, sizeof(sun.sun_path));
3197 if (connect(fd3, (struct sockaddr *)&sun, sizeof(sun)) != 0) e(0);
3199 len = sizeof(sun);
3200 if ((fd4 = accept(fd2, (struct sockaddr *)&sun, &len)) >= 0) e(0);
3201 if (errno != EWOULDBLOCK) e(0);
3202 if ((fd4 = accept(fd, (struct sockaddr *)&sun, &len)) < 0) e(0);
3204 len = sizeof(sun);
3205 if (getpeername(fd3, (struct sockaddr *)&sun, &len) != 0) e(0);
3206 check_addr(&sun, len, SOCK_PATH_A);
3208 if (close(fd) != 0) e(0);
3209 if (close(fd2) != 0) e(0);
3210 if (close(fd3) != 0) e(0);
3211 if (close(fd4) != 0) e(0);
3213 if (unlink(SOCK_PATH_A) != 0) e(0);
3214 if (unlink(SOCK_PATH_B) != 0) e(0);
3218 * Test that non-canonized path names are accepted and returned.
3219 * Also test datagram send errors on disconnect.
3221 static void
3222 test90s(void)
3224 struct sockaddr_un sun;
3225 socklen_t len;
3226 int fd, fd2;
3228 subtest = 19;
3230 fd = get_bound_socket(SOCK_DGRAM, SOCK_PATH_A_X, &sun);
3232 if ((fd2 = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) e(0);
3234 memset(&sun, 0, sizeof(sun));
3235 sun.sun_family = AF_UNIX;
3236 strlcpy(sun.sun_path, SOCK_PATH_A_Y, sizeof(sun.sun_path));
3238 if (connect(fd2, (struct sockaddr *)&sun, sizeof(sun)) != 0) e(0);
3240 len = sizeof(sun);
3241 if (getpeername(fd2, (struct sockaddr *)&sun, &len) != 0) e(0);
3242 check_addr(&sun, len, SOCK_PATH_A_X);
3244 if (send(fd2, "A", 1, 0) != 1) e(0);
3246 if (close(fd) != 0) e(0);
3248 if (send(fd2, "B", 1, 0) != -1) e(0);
3249 if (errno != ECONNRESET) e(0);
3251 if (send(fd2, "B", 1, 0) != -1) e(0);
3252 if (errno != EDESTADDRREQ) e(0);
3254 if (close(fd2) != 0) e(0);
3256 if (unlink(SOCK_PATH_A) != 0) e(0);
3260 * Test basic sysctl(2) socket enumeration for a specific socket type.
3262 static void
3263 sub90t(int type, const char * path)
3265 struct kinfo_pcb *ki;
3266 size_t i, len, oldlen;
3267 int fd, mib[8];
3269 if ((fd = socket(AF_UNIX, type, 0)) < 0) e(0);
3271 memset(mib, 0, sizeof(mib));
3273 len = __arraycount(mib);
3274 if (sysctlnametomib(path, mib, &len) != 0) e(0);
3275 if (len != 4) e(0);
3277 if (sysctl(mib, __arraycount(mib), NULL, &oldlen, NULL, 0) != 0) e(0);
3278 if (oldlen == 0) e(0);
3279 if (oldlen % sizeof(*ki)) e(0);
3281 if ((ki = (struct kinfo_pcb *)malloc(oldlen)) == NULL) e(0);
3283 if (sysctl(mib, __arraycount(mib), ki, &oldlen, NULL, 0) != 0) e(0);
3284 if (oldlen == 0) e(0);
3285 if (oldlen % sizeof(*ki)) e(0);
3288 * We cannot check a whole lot of things, because we have no way of
3289 * knowing which is the socket we created. Check some basics and leave
3290 * it at that. This subtest is mostly trying to guarantee that
3291 * netstat(1) will not show nothing, anyway.
3293 for (i = 0; i < oldlen / sizeof(*ki); i++) {
3294 if (ki[i].ki_pcbaddr == 0) e(0);
3295 if (ki[i].ki_sockaddr == 0) e(0);
3296 if (ki[i].ki_family != AF_UNIX) e(0);
3297 if (ki[i].ki_type != type) e(0);
3298 if (ki[i].ki_protocol != 0) e(0);
3301 free(ki);
3303 if (close(fd) != 0) e(0);
3307 * Test basic sysctl(2) socket enumeration support.
3309 static void
3310 test90t(void)
3313 subtest = 20;
3316 * We test that for each of the socket types, when we create a socket,
3317 * we can find at least one socket of that type in the respective
3318 * sysctl(2) out.
3320 sub90t(SOCK_STREAM, "net.local.stream.pcblist");
3322 sub90t(SOCK_SEQPACKET, "net.local.seqpacket.pcblist");
3324 sub90t(SOCK_DGRAM, "net.local.dgram.pcblist");
3328 * Cause a pending recv() call to return. Here 'fd' is the file descriptor
3329 * identifying the other end of the socket pair. If breaking the recv()
3330 * requires sending data, 'data' and 'len' identify the data that should be
3331 * sent. Return 'fd' if it is still open, or -1 if it is closed.
3333 static int
3334 break_uds_recv(int fd, const char * data, size_t len)
3336 int fd2;
3339 * This UDS-specific routine makes the recv() in one of two ways
3340 * depending on whether the recv() call already made partial progress:
3341 * if it did, this send call creates a segment boundary which should
3342 * cut short the current receive call. If it did not, the send call
3343 * will simply satisfy the receive call with regular data.
3345 if ((fd2 = open("/dev/null", O_RDONLY)) < 0) e(0);
3347 if (send_fds(fd, data, len, 0, NULL, 0, &fd2, 1) != len) e(0);
3349 if (close(fd2) != 0) e(0);
3351 return fd;
3355 * Test for receiving on stream sockets. In particular, test SO_RCVLOWAT,
3356 * MSG_PEEK, MSG_DONTWAIT, and MSG_WAITALL.
3358 static void
3359 test90u(void)
3362 subtest = 21;
3364 socklib_stream_recv(socketpair, AF_UNIX, SOCK_STREAM, break_uds_recv);
3367 #define MAX_BYTES 2 /* set to 3 for slightly better(?) testing */
3368 #define USLEEP_TIME 250000 /* increase on wimpy platforms if needed */
3371 * Signal handler which just needs to exist, so that invoking it will interrupt
3372 * an ongoing system call.
3374 static void
3375 test90_got_signal(int sig __unused)
3378 /* Nothing. */
3382 * Test for sending on stream sockets. The quick summary here is that send()
3383 * should basically act as the mirror of recv(MSG_WAITALL), i.e., it should
3384 * keep suspending until all data is sent (or the call is interrupted or no
3385 * more can possibly be sent), and, SO_SNDLOWAT, mirroring SO_RCVLOWAT, acts as
3386 * an admission test for the send: nothing is sent until there is room in the
3387 * send buffer (i.e., the peer's receive buffer) for at least the low send
3388 * watermark, or the whole send request length, whichever is smaller. In
3389 * addition, select(2) should use the same threshold.
3391 static void
3392 sub90v(int iroom, int istate, int slowat, int len, int bits, int act)
3394 const char *data = "ABC"; /* this limits MAX_BYTES to 3 */
3395 struct sigaction sa;
3396 struct timeval tv;
3397 fd_set fds;
3398 char buf[2], *sndbuf;
3399 pid_t pid;
3400 int fd[2], rcvlen, min, flags, res, err;
3401 int pfd[2], eroom, tstate, fl, status;
3403 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != 0) e(0);
3406 * Set up the initial condition on the sockets.
3408 rcvlen = get_rcvbuf_len(fd[1]);
3409 if (rcvlen <= iroom) e(0);
3410 rcvlen -= iroom;
3412 if ((sndbuf = malloc(rcvlen)) == NULL) e(0);
3414 memset(sndbuf, 'X', rcvlen);
3415 if (send(fd[0], sndbuf, rcvlen, 0) != rcvlen) e(0);
3417 free(sndbuf);
3419 switch (istate) {
3420 case 0: break;
3421 case 1: if (shutdown(fd[0], SHUT_WR) != 0) e(0); break;
3422 case 2: if (shutdown(fd[1], SHUT_RD) != 0) e(0); break;
3423 case 3: if (close(fd[1]) != 0) e(0); break;
3426 if (setsockopt(fd[0], SOL_SOCKET, SO_SNDLOWAT, &slowat,
3427 sizeof(slowat)) != 0) e(0);
3429 /* SO_SNDLOWAT is always bounded by the actual send length. */
3430 min = MIN(len, slowat);
3432 flags = MSG_NOSIGNAL;
3433 if (bits & 1) flags |= MSG_DONTWAIT;
3436 * Do a quick select test to see if its result indeed matches whether
3437 * the available space in the "send" buffer meets the threshold.
3439 FD_ZERO(&fds);
3440 FD_SET(fd[0], &fds);
3441 tv.tv_sec = 0;
3442 tv.tv_usec = 0;
3443 res = select(fd[0] + 1, NULL, &fds, NULL, &tv);
3444 if (res < 0 || res > 1) e(0);
3445 if (res != (iroom >= slowat || istate > 0)) e(0);
3446 if (res == 1 && !FD_ISSET(fd[0], &fds)) e(0);
3449 * Cut short a whole lot of cases, to avoid the overhead of forking,
3450 * namely when we know the call should return immediately. This is the
3451 * case when the socket state disallows further sending, or when all
3452 * data could be sent, or when the call was non-blocking. The low
3453 * send watermark only helps determine whether anything was sent here.
3455 if (istate > 0 || iroom >= len || (flags & MSG_DONTWAIT)) {
3456 res = send(fd[0], data, len, flags);
3458 if (istate > 0) {
3459 if (res != -1) e(0);
3460 if (errno != EPIPE) e(0);
3461 } else if (iroom >= len) {
3462 if (res != len) e(0);
3463 } else if (iroom >= min) {
3464 if (res != iroom) e(0);
3465 } else {
3466 if (res != -1) e(0);
3467 if (errno != EWOULDBLOCK) e(0);
3470 /* Early cleanup and return to avoid even more code clutter. */
3471 if (istate != 3 && close(fd[1]) != 0) e(0);
3472 if (close(fd[0]) != 0) e(0);
3474 return;
3478 * Now starts the interesting stuff: the send call should now block,
3479 * even though if we add MSG_DONTWAIT it may not return EWOULDBLOCK,
3480 * because MSG_DONTWAIT prevents the send from blocking after partial
3481 * completion. As such, we can only test our expectations by letting
3482 * the call block, in a child process, and waiting. We do test as much
3483 * of the above assumption as we can for safety right here, but this is
3484 * not a substitute for actually blocking even in these cases!
3486 if (iroom < min) {
3487 if (send(fd[0], data, len, flags | MSG_DONTWAIT) != -1) e(0);
3488 if (errno != EWOULDBLOCK) e(0);
3492 * If (act < 9), we receive 0, 1, or 2 bytes from the receive queue
3493 * before forcing the send call to terminate in one of three ways.
3495 * If (act == 9), we use a signal to interrupt the send call.
3497 if (act < 9) {
3498 eroom = act % 3;
3499 tstate = act / 3;
3500 } else
3501 eroom = tstate = 0;
3503 if (pipe2(pfd, O_NONBLOCK) != 0) e(0);
3505 pid = fork();
3506 switch (pid) {
3507 case 0:
3508 errct = 0;
3510 if (close(fd[1]) != 0) e(0);
3511 if (close(pfd[0]) != 0) e(0);
3513 if (act == 9) {
3514 memset(&sa, 0, sizeof(sa));
3515 sa.sa_handler = test90_got_signal;
3516 if (sigaction(SIGUSR1, &sa, NULL) != 0) e(0);
3519 res = send(fd[0], data, len, flags);
3520 err = errno;
3522 if (write(pfd[1], &res, sizeof(res)) != sizeof(res)) e(0);
3523 if (write(pfd[1], &err, sizeof(err)) != sizeof(err)) e(0);
3525 exit(errct);
3526 case -1:
3527 e(0);
3530 if (close(pfd[1]) != 0) e(0);
3533 * Allow the child to enter the blocking send(2), and check the pipe
3534 * to see if it is really blocked.
3536 if (usleep(USLEEP_TIME) != 0) e(0);
3538 if (read(pfd[0], &res, sizeof(res)) != -1) e(0);
3539 if (errno != EAGAIN) e(0);
3541 if (eroom > 0) {
3542 if (recv(fd[1], buf, eroom, 0) != eroom) e(0);
3545 * The threshold for the send is now met if the entire request
3546 * has been satisfied.
3548 if (iroom + eroom >= len) {
3549 if ((fl = fcntl(pfd[0], F_GETFL)) == -1) e(0);
3550 if (fcntl(pfd[0], F_SETFL, fl & ~O_NONBLOCK) != 0)
3551 e(0);
3553 if (read(pfd[0], &res, sizeof(res)) != sizeof(res))
3554 e(0);
3555 if (read(pfd[0], &err, sizeof(err)) != sizeof(err))
3556 e(0);
3558 if (res != len) e(0);
3560 /* Bail out. */
3561 goto cleanup;
3565 if (act < 9) {
3567 * Now test various ways to terminate the send call. Ideally
3568 * we would also like to have a case that raises a socket error
3569 * here, but with UDS there is currently no way to do that.
3571 switch (tstate) {
3572 case 0: if (shutdown(fd[0], SHUT_WR) != 0) e(0); break;
3573 case 1: if (shutdown(fd[1], SHUT_RD) != 0) e(0); break;
3574 case 2: if (close(fd[1]) != 0) e(0); fd[1] = -1; break;
3576 } else
3577 if (kill(pid, SIGUSR1) != 0) e(0);
3579 if ((fl = fcntl(pfd[0], F_GETFL)) == -1) e(0);
3580 if (fcntl(pfd[0], F_SETFL, fl & ~O_NONBLOCK) != 0) e(0);
3582 if (read(pfd[0], &res, sizeof(res)) != sizeof(res)) e(0);
3583 if (read(pfd[0], &err, sizeof(err)) != sizeof(err)) e(0);
3586 * If the send met the threshold before being terminate or interrupted,
3587 * we should at least have sent something. Otherwise, the send was
3588 * never admitted and should return EPIPE (if the send was terminated)
3589 * or EINTR (if the child was killed).
3591 if (iroom + eroom >= min) {
3592 if (res != MIN(iroom + eroom, len)) e(0);
3593 } else {
3594 if (res != -1) e(0);
3595 if (act < 9) {
3596 if (err != EPIPE) e(0);
3597 } else
3598 if (err != EINTR) e(0);
3601 cleanup:
3602 if (close(pfd[0]) != 0) e(0);
3604 if (wait(&status) != pid) e(0);
3605 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0);
3607 if (fd[1] != -1 && close(fd[1]) != 0) e(0);
3608 if (close(fd[0]) != 0) e(0);
3612 * Test for sending on stream sockets. In particular, test SO_SNDLOWAT and
3613 * MSG_DONTWAIT.
3615 static void
3616 test90v(void)
3618 int iroom, istate, slowat, len, bits, act;
3620 subtest = 22;
3622 /* Insanity. */
3623 for (iroom = 0; iroom <= MAX_BYTES; iroom++)
3624 for (istate = 0; istate <= 3; istate++)
3625 for (slowat = 1; slowat <= MAX_BYTES; slowat++)
3626 for (len = 1; len <= MAX_BYTES; len++)
3627 for (bits = 0; bits < 2; bits++)
3628 for (act = 0; act <= 9; act++)
3629 sub90v(iroom, istate,
3630 slowat, len, bits,
3631 act);
3635 * Test that SO_RCVLOWAT is limited to the size of the receive buffer.
3637 static void
3638 sub90w_recv(int fill_delta, int rlowat_delta, int exp_delta)
3640 char *buf;
3641 int fd[2], rcvlen, fill, rlowat, res;
3643 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != 0) e(0);
3645 rcvlen = get_rcvbuf_len(fd[0]);
3647 if ((buf = malloc(rcvlen + 1)) == NULL) e(0);
3649 fill = rcvlen + fill_delta;
3650 rlowat = rcvlen + rlowat_delta;
3652 memset(buf, 0, fill);
3654 if (send(fd[1], buf, fill, 0) != fill) e(0);
3656 if (setsockopt(fd[0], SOL_SOCKET, SO_RCVLOWAT, &rlowat,
3657 sizeof(rlowat)) != 0) e(0);
3659 res = recv(fd[0], buf, rcvlen + 1, MSG_DONTWAIT);
3660 if (exp_delta < 0) {
3661 if (res != -1) e(0);
3662 if (errno != EWOULDBLOCK) e(0);
3663 } else
3664 if (res != rcvlen - exp_delta) e(0);
3666 free(buf);
3668 if (close(fd[0]) != 0) e(0);
3669 if (close(fd[1]) != 0) e(0);
3673 * Test that SO_SNDLOWAT is limited to the size of the "send" buffer.
3675 static void
3676 sub90w_send(int fill, int slowat_delta, int exp_delta)
3678 char *buf;
3679 socklen_t len;
3680 int fd[2], sndlen, slowat, res;
3682 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != 0) e(0);
3684 len = sizeof(sndlen);
3685 if (getsockopt(fd[0], SOL_SOCKET, SO_SNDBUF, &sndlen, &len) != 0) e(0);
3686 if (len != sizeof(sndlen)) e(0);
3688 if ((buf = malloc(sndlen + 1)) == NULL) e(0);
3690 slowat = sndlen + slowat_delta;
3692 if (fill > 0) {
3693 memset(buf, 0, fill);
3695 if (send(fd[0], buf, fill, 0) != fill) e(0);
3698 if (setsockopt(fd[0], SOL_SOCKET, SO_SNDLOWAT, &slowat,
3699 sizeof(slowat)) != 0) e(0);
3701 res = send(fd[0], buf, sndlen + 1, MSG_DONTWAIT);
3702 if (exp_delta < 0) {
3703 if (res != -1) e(0);
3704 if (errno != EWOULDBLOCK) e(0);
3705 } else
3706 if (res != sndlen - exp_delta) e(0);
3708 free(buf);
3710 if (close(fd[0]) != 0) e(0);
3711 if (close(fd[1]) != 0) e(0);
3715 * Test that on stream sockets, SO_RCVLOWAT and SO_SNDLOWAT are limited to
3716 * their respective buffer sizes.
3718 static void
3719 test90w(void)
3722 subtest = 23;
3725 * With the receive buffer filled except for one byte, all data should
3726 * be retrieved unless the threshold is not met.
3728 sub90w_recv(-1, -1, 1);
3729 sub90w_recv(-1, 0, -1);
3730 sub90w_recv(-1, 1, -1);
3733 * With the receive buffer filled completely, all data should be
3734 * retrieved in all cases.
3736 sub90w_recv(0, -1, 0);
3737 sub90w_recv(0, 0, 0);
3738 sub90w_recv(0, 1, 0);
3741 * With a "send" buffer that contains one byte, all data should be sent
3742 * unless the threshold is not met.
3744 sub90w_send(1, -1, 1);
3745 sub90w_send(1, 0, -1);
3746 sub90w_send(1, 1, -1);
3749 * With the "send" buffer filled completely, all data should be sent
3750 * in all cases.
3752 sub90w_send(0, -1, 0);
3753 sub90w_send(0, 0, 0);
3754 sub90w_send(0, 1, 0);
3758 * Test shutdown on listening sockets.
3760 static void
3761 sub90x(int type, int how, int connwait)
3763 struct sockaddr_un sun;
3764 socklen_t len;
3765 char buf[1];
3766 int fd, fd2, fd3, val, fl;
3768 subtest = 24;
3770 fd = get_bound_socket(type, SOCK_PATH_A, &sun);
3772 if (listen(fd, 5) != 0) e(0);
3774 if (!connwait) {
3775 if ((fd2 = socket(AF_UNIX, type, 0)) < 0) e(0);
3777 if (connect(fd2, (struct sockaddr *)&sun, sizeof(sun)) != 0)
3778 e(0);
3779 } else {
3780 val = 1;
3781 if (setsockopt(fd, 0, LOCAL_CONNWAIT, &val, sizeof(val)) != 0)
3782 e(0);
3784 if ((fd2 = socket(AF_UNIX, type | SOCK_NONBLOCK, 0)) < 0) e(0);
3786 if (connect(fd2, (struct sockaddr *)&sun, sizeof(sun)) != -1)
3787 e(0);
3788 if (errno != EINPROGRESS) e(0);
3791 if (shutdown(fd, how) != 0) e(0);
3793 len = sizeof(sun);
3794 if ((fd3 = accept(fd, (struct sockaddr *)&sun, &len)) < 0) e(0);
3796 if (write(fd2, "A", 1) != 1) e(0);
3797 if (read(fd3, buf, 1) != 1) e(0);
3798 if (buf[0] != 'A') e(0);
3800 if (write(fd3, "B", 1) != 1) e(0);
3801 if (read(fd2, buf, 1) != 1) e(0);
3802 if (buf[0] != 'B') e(0);
3804 len = sizeof(sun);
3805 if (accept(fd, (struct sockaddr *)&sun, &len) != -1) e(0);
3806 if (errno != ECONNABORTED) e(0);
3809 * Strangely, both NetBSD and Linux (yes, my two reference platforms)
3810 * return EWOULDBLOCK from non-blocking accept(2) calls even though
3811 * they always return ECONNABORTED when blocking. For consistency and
3812 * select(2), we always return ECONNABORTED.
3814 if ((fl = fcntl(fd, F_GETFL)) == -1) e(0);
3815 if (fcntl(fd, F_SETFL, fl | O_NONBLOCK) != 0) e(0);
3817 len = sizeof(sun);
3818 if (accept(fd, (struct sockaddr *)&sun, &len) != -1) e(0);
3819 if (errno != ECONNABORTED) e(0);
3821 if (fcntl(fd, F_SETFL, fl) != 0) e(0);
3823 if (close(fd3) != 0) e(0);
3824 if (close(fd2) != 0) e(0);
3826 if ((fd2 = socket(AF_UNIX, type | SOCK_NONBLOCK, 0)) < 0) e(0);
3828 if (connect(fd2, (struct sockaddr *)&sun, sizeof(sun)) != -1) e(0);
3829 if (errno != ECONNREFUSED) e(0);
3831 len = sizeof(sun);
3832 if (accept(fd, (struct sockaddr *)&sun, &len) != -1) e(0);
3833 if (errno != ECONNABORTED) e(0);
3835 if (close(fd2) != 0) e(0);
3836 if (close(fd) != 0) e(0);
3838 if (unlink(SOCK_PATH_A) != 0) e(0);
3842 * Test shutdown on listening sockets. Pending connections should still be
3843 * acceptable (and not inherit the shutdown flags), but new connections must be
3844 * refused, and the accept call must no longer ever block.
3846 static void
3847 test90x(void)
3849 const int types[] = { SOCK_STREAM, SOCK_SEQPACKET };
3850 const int hows[] = { SHUT_RD, SHUT_WR, SHUT_RDWR };
3851 unsigned int i, j, k;
3853 for (i = 0; i < __arraycount(types); i++)
3854 for (j = 0; j < __arraycount(hows); j++)
3855 for (k = 0; k <= 1; k++)
3856 sub90x(types[i], hows[j], k);
3860 * Test accepting connections without LOCAL_CONNWAIT for the given socket type.
3862 static void
3863 sub90y(int type)
3865 struct sockaddr_un sunA, sunB, sunC;
3866 socklen_t len;
3867 struct timeval tv;
3868 fd_set fds;
3869 char buf[7];
3870 uid_t uid;
3871 gid_t gid;
3872 int fd, fd2, fd3, fd4, val;
3874 fd = get_bound_socket(type | SOCK_NONBLOCK, SOCK_PATH_A, &sunA);
3876 len = sizeof(val);
3877 if (getsockopt(fd, 0, LOCAL_CONNWAIT, &val, &len) != 0) e(0);
3878 if (len != sizeof(val)) e(0);
3879 if (val != 0) e(0);
3881 if (listen(fd, 5) != 0) e(0);
3884 * Any socket options should be inherited from the listening socket at
3885 * connect time, and not be re-inherited at accept time. It does not
3886 * really matter what socket option we set here, as long as it is
3887 * supposed to be inherited.
3889 val = 123;
3890 if (setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &val, sizeof(val)) != 0)
3891 e(0);
3893 fd2 = get_bound_socket(type, SOCK_PATH_B, &sunB);
3895 if (connect(fd2, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
3897 val = 456;
3898 if (setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &val, sizeof(val)) != 0)
3899 e(0);
3902 * Obtaining the peer name should work. As always, the name should be
3903 * inherited from the listening socket.
3905 len = sizeof(sunC);
3906 if (getpeername(fd2, (struct sockaddr *)&sunC, &len) != 0) e(0);
3907 check_addr(&sunC, len, SOCK_PATH_A);
3910 * Obtaining peer credentials should work. This is why NetBSD obtains
3911 * the peer credentials at bind time, not at accept time.
3913 if (getpeereid(fd2, &uid, &gid) != 0) e(0);
3914 if (uid != geteuid()) e(0);
3915 if (gid != getegid()) e(0);
3918 * Sending to the socket should work, and it should be possible to
3919 * receive the data from the other side once accepted.
3921 if (send(fd2, "Hello, ", 7, 0) != 7) e(0);
3922 if (send(fd2, "world!", 6, 0) != 6) e(0);
3924 /* Shutdown settings should be visible after accepting, too. */
3925 if (shutdown(fd2, SHUT_RDWR) != 0) e(0);
3927 len = sizeof(sunB);
3928 if ((fd3 = accept(fd, (struct sockaddr *)&sunB, &len)) < 0) e(0);
3929 check_addr(&sunB, len, SOCK_PATH_B);
3931 len = sizeof(val);
3932 if (getsockopt(fd3, SOL_SOCKET, SO_SNDLOWAT, &val, &len) != 0) e(0);
3933 if (len != sizeof(val)) e(0);
3934 if (val != 123) e(0);
3936 if (recv(fd3, buf, 7, 0) != 7) e(0);
3937 if (memcmp(buf, "Hello, ", 7) != 0) e(0);
3938 if (recv(fd3, buf, 7, 0) != 6) e(0);
3939 if (memcmp(buf, "world!", 6) != 0) e(0);
3941 if (recv(fd3, buf, sizeof(buf), 0) != 0) e(0);
3943 if (send(fd3, "X", 1, MSG_NOSIGNAL) != -1) e(0);
3944 if (errno != EPIPE) e(0);
3946 if (close(fd2) != 0) e(0);
3947 if (close(fd3) != 0) e(0);
3949 if (unlink(SOCK_PATH_B) != 0) e(0);
3952 * If the socket pending acceptance is closed, the listening socket
3953 * should pretend as though the connection was never there.
3955 if ((fd2 = socket(AF_UNIX, type, 0)) < 0) e(0);
3957 if (connect(fd2, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
3959 FD_ZERO(&fds);
3960 FD_SET(fd, &fds);
3961 tv.tv_sec = 0;
3962 tv.tv_usec = 0;
3963 if (select(fd + 1, &fds, NULL, NULL, &tv) != 1) e(0);
3964 if (!FD_ISSET(fd, &fds)) e(0);
3966 if (close(fd2) != 0) e(0);
3968 if (select(fd + 1, &fds, NULL, NULL, &tv) != 0) e(0);
3969 if (FD_ISSET(fd, &fds)) e(0);
3971 len = sizeof(sunB);
3972 if (accept(fd, (struct sockaddr *)&sunB, &len) != -1) e(0);
3973 if (errno != EWOULDBLOCK) e(0);
3976 * Try the same thing, but now with the connection sandwiched between
3977 * two different pending connections, which should be left intact.
3979 if ((fd2 = socket(AF_UNIX, type, 0)) < 0) e(0);
3981 if (connect(fd2, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
3983 if (send(fd2, "A", 1, 0) != 1) e(0);
3985 if ((fd3 = socket(AF_UNIX, type, 0)) < 0) e(0);
3987 if (connect(fd3, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
3989 if (send(fd3, "B", 1, 0) != 1) e(0);
3991 if ((fd4 = socket(AF_UNIX, type, 0)) < 0) e(0);
3993 if (connect(fd4, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
3995 if (send(fd4, "C", 1, 0) != 1) e(0);
3997 if (close(fd3) != 0) e(0);
3999 len = sizeof(sunB);
4000 if ((fd3 = accept(fd, (struct sockaddr *)&sunB, &len)) < 0) e(0);
4002 if (recv(fd3, buf, sizeof(buf), 0) != 1) e(0);
4003 if (buf[0] != 'A') e(0);
4005 if (close(fd3) != 0) e(0);
4006 if (close(fd2) != 0) e(0);
4008 FD_ZERO(&fds);
4009 FD_SET(fd, &fds);
4010 tv.tv_sec = 0;
4011 tv.tv_usec = 0;
4012 if (select(fd + 1, &fds, NULL, NULL, &tv) != 1) e(0);
4013 if (!FD_ISSET(fd, &fds)) e(0);
4015 len = sizeof(sunB);
4016 if ((fd3 = accept(fd, (struct sockaddr *)&sunB, &len)) < 0) e(0);
4018 if (recv(fd3, buf, sizeof(buf), 0) != 1) e(0);
4019 if (buf[0] != 'C') e(0);
4021 if (close(fd3) != 0) e(0);
4022 if (close(fd4) != 0) e(0);
4024 if (select(fd + 1, &fds, NULL, NULL, &tv) != 0) e(0);
4025 if (FD_ISSET(fd, &fds)) e(0);
4027 len = sizeof(sunB);
4028 if (accept(fd, (struct sockaddr *)&sunB, &len) != -1) e(0);
4029 if (errno != EWOULDBLOCK) e(0);
4032 * If the listening socket is closed, the socket pending acceptance
4033 * should be reset. We actually rely on this behavior in the sweep
4034 * test, but we test this with more than one socket this time.
4036 if ((fd2 = socket(AF_UNIX, type, 0)) < 0) e(0);
4038 if (connect(fd2, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
4040 if ((fd3 = socket(AF_UNIX, type, 0)) < 0) e(0);
4042 if (connect(fd3, (struct sockaddr *)&sunA, sizeof(sunA)) != 0) e(0);
4044 if (close(fd) != 0) e(0);
4046 if (recv(fd2, buf, sizeof(buf), 0) != -1) e(0);
4047 if (errno != ECONNRESET) e(0);
4049 if (recv(fd2, buf, sizeof(buf), 0) != 0) e(0);
4051 if (recv(fd3, buf, sizeof(buf), 0) != -1) e(0);
4052 if (errno != ECONNRESET) e(0);
4054 if (recv(fd3, buf, sizeof(buf), 0) != 0) e(0);
4056 if (close(fd3) != 0) e(0);
4058 if (close(fd2) != 0) e(0);
4060 if (unlink(SOCK_PATH_A) != 0) e(0);
4064 * Test accepting connections without LOCAL_CONNWAIT. Since both the old UDS
4065 * service and the initial version of the new UDS service supported only the
4066 * LOCAL_CONNWAIT behavior, the alternative (which is now the default, as it is
4067 * on other platforms) has been a bit under-tested so far.
4069 static void
4070 test90y(void)
4073 subtest = 25;
4075 sub90y(SOCK_STREAM);
4077 sub90y(SOCK_SEQPACKET);
4081 * Test that SO_LINGER has no effect on sockets of the given type.
4083 static void
4084 sub90z(int type)
4086 struct sockaddr_un sun;
4087 socklen_t len;
4088 struct linger l;
4089 char buf[1];
4090 int fd, fd2, fd3;
4092 fd = get_bound_socket(type, SOCK_PATH_A, &sun);
4094 if (listen(fd, 1) != 0) e(0);
4096 if ((fd2 = socket(AF_UNIX, type, 0)) < 0) e(0);
4098 if (connect(fd2, (struct sockaddr *)&sun, sizeof(sun)) != 0) e(0);
4100 len = sizeof(sun);
4101 if ((fd3 = accept(fd, (struct sockaddr *)&sun, &len)) < 0) e(0);
4103 if (close(fd) != 0) e(0);
4105 if (send(fd2, "A", 1, 0) != 1) e(0);
4107 l.l_onoff = 1;
4108 l.l_linger = 0;
4109 if (setsockopt(fd2, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) != 0) e(0);
4111 if (close(fd2) != 0) e(0);
4113 if (recv(fd3, buf, sizeof(buf), 0) != 1) e(0);
4114 if (buf[0] != 'A') e(0);
4116 /* We should not get ECONNRESET now. */
4117 if (recv(fd3, buf, sizeof(buf), 0) != 0) e(0);
4119 if (close(fd3) != 0) e(0);
4121 if (unlink(SOCK_PATH_A) != 0) e(0);
4125 * Test that SO_LINGER has no effect on UNIX domain sockets. In particular, a
4126 * timeout of zero does not cause the connection to be reset forcefully.
4128 static void
4129 test90z(void)
4132 subtest = 26;
4134 sub90z(SOCK_STREAM);
4136 sub90z(SOCK_SEQPACKET);
4140 * Test program for UDS.
4143 main(int argc, char ** argv)
4145 int i, m;
4147 start(90);
4149 if (argc == 2)
4150 m = atoi(argv[1]);
4151 else
4152 m = 0xFFFFFFF;
4154 for (i = 0; i < ITERATIONS; i++) {
4155 if (m & 0x0000001) test90a();
4156 if (m & 0x0000002) test90b();
4157 if (m & 0x0000004) test90c();
4158 if (m & 0x0000008) test90d();
4159 if (m & 0x0000010) test90e();
4160 if (m & 0x0000020) test90f();
4161 if (m & 0x0000040) test90g();
4162 if (m & 0x0000080) test90h();
4163 if (m & 0x0000100) test90i();
4164 if (m & 0x0000200) test90j();
4165 if (m & 0x0000400) test90k();
4166 if (m & 0x0000800) test90l();
4167 if (m & 0x0001000) test90m();
4168 if (m & 0x0002000) test90n();
4169 if (m & 0x0004000) test90o();
4170 if (m & 0x0008000) test90p();
4171 if (m & 0x0010000) test90q();
4172 if (m & 0x0020000) test90r();
4173 if (m & 0x0040000) test90s();
4174 if (m & 0x0080000) test90t();
4175 if (m & 0x0100000) test90u();
4176 if (m & 0x0200000) test90v();
4177 if (m & 0x0400000) test90w();
4178 if (m & 0x0800000) test90x();
4179 if (m & 0x1000000) test90y();
4180 if (m & 0x2000000) test90z();
4183 quit();
4184 /* NOTREACHED */