xref: /aosp_15_r20/external/liburing/test/accept.c (revision 25da2bea747f3a93b4c30fd9708b0618ef55a0e6)
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Check that IORING_OP_ACCEPT works, and send some data across to verify we
4  * didn't get a junk fd.
5  */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <assert.h>
10 #include <limits.h>
11 
12 #include <errno.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15 #include <sys/socket.h>
16 #include <sys/time.h>
17 #include <sys/resource.h>
18 #include <sys/un.h>
19 #include <netinet/tcp.h>
20 #include <netinet/in.h>
21 #include <arpa/inet.h>
22 
23 #include "helpers.h"
24 #include "liburing.h"
25 
26 #define MAX_FDS 32
27 static int no_accept;
28 static int no_accept_multi;
29 
30 struct data {
31 	char buf[128];
32 	struct iovec iov;
33 };
34 
35 struct accept_test_args {
36 	int accept_should_error;
37 	bool fixed;
38 	bool nonblock;
39 	bool queue_accept_before_connect;
40 	bool multishot;
41 	int extra_loops;
42 };
43 
close_fds(int fds[],int nr)44 static void close_fds(int fds[], int nr)
45 {
46 	int i;
47 
48 	for (i = 0; i < nr; i++)
49 		close(fds[i]);
50 }
51 
close_sock_fds(int s_fd[],int c_fd[],int nr,bool fixed)52 static void close_sock_fds(int s_fd[], int c_fd[], int nr, bool fixed)
53 {
54 	if (!fixed)
55 		close_fds(s_fd, nr);
56 	close_fds(c_fd, nr);
57 }
58 
queue_send(struct io_uring * ring,int fd)59 static void queue_send(struct io_uring *ring, int fd)
60 {
61 	struct io_uring_sqe *sqe;
62 	struct data *d;
63 
64 	d = t_malloc(sizeof(*d));
65 	d->iov.iov_base = d->buf;
66 	d->iov.iov_len = sizeof(d->buf);
67 
68 	sqe = io_uring_get_sqe(ring);
69 	io_uring_prep_writev(sqe, fd, &d->iov, 1, 0);
70 	sqe->user_data = 1;
71 }
72 
queue_recv(struct io_uring * ring,int fd,bool fixed)73 static void queue_recv(struct io_uring *ring, int fd, bool fixed)
74 {
75 	struct io_uring_sqe *sqe;
76 	struct data *d;
77 
78 	d = t_malloc(sizeof(*d));
79 	d->iov.iov_base = d->buf;
80 	d->iov.iov_len = sizeof(d->buf);
81 
82 	sqe = io_uring_get_sqe(ring);
83 	io_uring_prep_readv(sqe, fd, &d->iov, 1, 0);
84 	sqe->user_data = 2;
85 	if (fixed)
86 		sqe->flags |= IOSQE_FIXED_FILE;
87 }
88 
queue_accept_conn(struct io_uring * ring,int fd,struct accept_test_args args)89 static void queue_accept_conn(struct io_uring *ring, int fd,
90 			      struct accept_test_args args)
91 {
92 	struct io_uring_sqe *sqe;
93 	int ret;
94 	int fixed_idx = args.fixed ? 0 : -1;
95 	int count = 1 + args.extra_loops;
96 	bool multishot = args.multishot;
97 
98 	while (count--) {
99 		sqe = io_uring_get_sqe(ring);
100 		if (fixed_idx < 0) {
101 			if (!multishot)
102 				io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
103 			else
104 				io_uring_prep_multishot_accept(sqe, fd, NULL,
105 							       NULL, 0);
106 		} else {
107 			if (!multishot)
108 				io_uring_prep_accept_direct(sqe, fd, NULL, NULL,
109 							    0, fixed_idx);
110 			else
111 				io_uring_prep_multishot_accept_direct(sqe, fd,
112 								      NULL, NULL,
113 								      0);
114 		}
115 
116 		ret = io_uring_submit(ring);
117 		assert(ret != -1);
118 	}
119 }
120 
accept_conn(struct io_uring * ring,int fixed_idx,bool multishot)121 static int accept_conn(struct io_uring *ring, int fixed_idx, bool multishot)
122 {
123 	struct io_uring_cqe *cqe;
124 	int ret;
125 
126 	ret = io_uring_wait_cqe(ring, &cqe);
127 	assert(!ret);
128 	ret = cqe->res;
129 	io_uring_cqe_seen(ring, cqe);
130 
131 	if (fixed_idx >= 0) {
132 		if (ret > 0) {
133 			if (!multishot) {
134 				close(ret);
135 				return -EINVAL;
136 			}
137 		} else if (!ret) {
138 			ret = fixed_idx;
139 		}
140 	}
141 	return ret;
142 }
143 
start_accept_listen(struct sockaddr_in * addr,int port_off,int extra_flags)144 static int start_accept_listen(struct sockaddr_in *addr, int port_off,
145 			       int extra_flags)
146 {
147 	int fd, ret;
148 
149 	fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC | extra_flags,
150 		    IPPROTO_TCP);
151 
152 	int32_t val = 1;
153 	ret = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
154 	assert(ret != -1);
155 	ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
156 	assert(ret != -1);
157 
158 	struct sockaddr_in laddr;
159 
160 	if (!addr)
161 		addr = &laddr;
162 
163 	addr->sin_family = AF_INET;
164 	addr->sin_port = htons(0x1235 + port_off);
165 	addr->sin_addr.s_addr = inet_addr("127.0.0.1");
166 
167 	ret = bind(fd, (struct sockaddr*)addr, sizeof(*addr));
168 	assert(ret != -1);
169 	ret = listen(fd, 128);
170 	assert(ret != -1);
171 
172 	return fd;
173 }
174 
set_client_fd(struct sockaddr_in * addr)175 static int set_client_fd(struct sockaddr_in *addr)
176 {
177 	int32_t val;
178 	int fd, ret;
179 
180 	fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
181 
182 	val = 1;
183 	ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
184 	assert(ret != -1);
185 
186 	int32_t flags = fcntl(fd, F_GETFL, 0);
187 	assert(flags != -1);
188 
189 	flags |= O_NONBLOCK;
190 	ret = fcntl(fd, F_SETFL, flags);
191 	assert(ret != -1);
192 
193 	ret = connect(fd, (struct sockaddr *)addr, sizeof(*addr));
194 	assert(ret == -1);
195 
196 	flags = fcntl(fd, F_GETFL, 0);
197 	assert(flags != -1);
198 
199 	flags &= ~O_NONBLOCK;
200 	ret = fcntl(fd, F_SETFL, flags);
201 	assert(ret != -1);
202 
203 	return fd;
204 }
205 
test_loop(struct io_uring * ring,struct accept_test_args args,int recv_s0,struct sockaddr_in * addr)206 static int test_loop(struct io_uring *ring,
207 		     struct accept_test_args args,
208 		     int recv_s0,
209 		     struct sockaddr_in *addr)
210 {
211 	struct io_uring_cqe *cqe;
212 	uint32_t head, count = 0;
213 	int i, ret, s_fd[MAX_FDS], c_fd[MAX_FDS], done = 0;
214 	bool fixed = args.fixed;
215 	bool multishot = args.multishot;
216 	uint32_t multishot_mask = 0;
217 	int nr_fds = multishot ? MAX_FDS : 1;
218 
219 	for (i = 0; i < nr_fds; i++)
220 		c_fd[i] = set_client_fd(addr);
221 
222 	if (!args.queue_accept_before_connect)
223 		queue_accept_conn(ring, recv_s0, args);
224 
225 	for (i = 0; i < nr_fds; i++) {
226 		s_fd[i] = accept_conn(ring, fixed ? 0 : -1, multishot);
227 		if (s_fd[i] == -EINVAL) {
228 			if (args.accept_should_error)
229 				goto out;
230 			fprintf(stdout,
231 				"%s %s Accept not supported, skipping\n",
232 				fixed ? "Fixed" : "",
233 				multishot ? "Multishot" : "");
234 			if (multishot)
235 				no_accept_multi = 1;
236 			else
237 				no_accept = 1;
238 			goto out;
239 		} else if (s_fd[i] < 0) {
240 			if (args.accept_should_error &&
241 			    (s_fd[i] == -EBADF || s_fd[i] == -EINVAL))
242 				goto out;
243 			fprintf(stderr, "%s %s Accept[%d] got %d\n",
244 				fixed ? "Fixed" : "",
245 				multishot ? "Multishot" : "",
246 				i, s_fd[i]);
247 			goto err;
248 		}
249 
250 		if (multishot && fixed) {
251 			if (s_fd[i] >= MAX_FDS) {
252 				fprintf(stderr,
253 					"Fixed Multishot Accept[%d] got outbound index: %d\n",
254 					i, s_fd[i]);
255 				goto err;
256 			}
257 			/*
258 			 * for fixed multishot accept test, the file slots
259 			 * allocated are [0, 32), this means we finally end up
260 			 * with each bit of a u32 being 1.
261 			 */
262 			multishot_mask |= (1U << s_fd[i]);
263 		}
264 	}
265 
266 	if (multishot) {
267 		if (fixed && (~multishot_mask != 0U)) {
268 			fprintf(stderr, "Fixed Multishot Accept misses events\n");
269 			goto err;
270 		}
271 		goto out;
272 	}
273 
274 	queue_send(ring, c_fd[0]);
275 	queue_recv(ring, s_fd[0], fixed);
276 
277 	ret = io_uring_submit_and_wait(ring, 2);
278 	assert(ret != -1);
279 
280 	while (count < 2) {
281 		io_uring_for_each_cqe(ring, head, cqe) {
282 			if (cqe->res < 0) {
283 				fprintf(stderr, "Got cqe res %d, user_data %i\n",
284 						cqe->res, (int)cqe->user_data);
285 				done = 1;
286 				break;
287 			}
288 			assert(cqe->res == 128);
289 			count++;
290 		}
291 
292 		assert(count <= 2);
293 		io_uring_cq_advance(ring, count);
294 		if (done)
295 			goto err;
296 	}
297 
298 out:
299 	close_sock_fds(s_fd, c_fd, nr_fds, fixed);
300 	return 0;
301 err:
302 	close_sock_fds(s_fd, c_fd, nr_fds, fixed);
303 	return 1;
304 }
305 
test(struct io_uring * ring,struct accept_test_args args)306 static int test(struct io_uring *ring, struct accept_test_args args)
307 {
308 	struct sockaddr_in addr;
309 	int ret = 0;
310 	int loop;
311 	int32_t recv_s0 = start_accept_listen(&addr, 0,
312 					      args.nonblock ? O_NONBLOCK : 0);
313 	if (args.queue_accept_before_connect)
314 		queue_accept_conn(ring, recv_s0, args);
315 	for (loop = 0; loop < 1 + args.extra_loops; loop++) {
316 		ret = test_loop(ring, args, recv_s0, &addr);
317 		if (ret)
318 			break;
319 	}
320 
321 	close(recv_s0);
322 	return ret;
323 }
324 
sig_alrm(int sig)325 static void sig_alrm(int sig)
326 {
327 	exit(0);
328 }
329 
test_accept_pending_on_exit(void)330 static int test_accept_pending_on_exit(void)
331 {
332 	struct io_uring m_io_uring;
333 	struct io_uring_cqe *cqe;
334 	struct io_uring_sqe *sqe;
335 	int fd, ret;
336 
337 	ret = io_uring_queue_init(32, &m_io_uring, 0);
338 	assert(ret >= 0);
339 
340 	fd = start_accept_listen(NULL, 0, 0);
341 
342 	sqe = io_uring_get_sqe(&m_io_uring);
343 	io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
344 	ret = io_uring_submit(&m_io_uring);
345 	assert(ret != -1);
346 
347 	signal(SIGALRM, sig_alrm);
348 	alarm(1);
349 	ret = io_uring_wait_cqe(&m_io_uring, &cqe);
350 	assert(!ret);
351 	io_uring_cqe_seen(&m_io_uring, cqe);
352 
353 	io_uring_queue_exit(&m_io_uring);
354 	return 0;
355 }
356 
357 struct test_accept_many_args {
358 	unsigned int usecs;
359 	bool nonblock;
360 	bool single_sock;
361 	bool close_fds;
362 };
363 
364 /*
365  * Test issue many accepts and see if we handle cancellation on exit
366  */
test_accept_many(struct test_accept_many_args args)367 static int test_accept_many(struct test_accept_many_args args)
368 {
369 	struct io_uring m_io_uring;
370 	struct io_uring_cqe *cqe;
371 	struct io_uring_sqe *sqe;
372 	unsigned long cur_lim;
373 	struct rlimit rlim;
374 	int *fds, i, ret;
375 	unsigned int nr = 128;
376 	int nr_socks = args.single_sock ? 1 : nr;
377 
378 	if (getrlimit(RLIMIT_NPROC, &rlim) < 0) {
379 		perror("getrlimit");
380 		return 1;
381 	}
382 
383 	cur_lim = rlim.rlim_cur;
384 	rlim.rlim_cur = nr / 4;
385 
386 	if (setrlimit(RLIMIT_NPROC, &rlim) < 0) {
387 		perror("setrlimit");
388 		return 1;
389 	}
390 
391 	ret = io_uring_queue_init(2 * nr, &m_io_uring, 0);
392 	assert(ret >= 0);
393 
394 	fds = t_calloc(nr_socks, sizeof(int));
395 
396 	for (i = 0; i < nr_socks; i++)
397 		fds[i] = start_accept_listen(NULL, i,
398 					     args.nonblock ? O_NONBLOCK : 0);
399 
400 	for (i = 0; i < nr; i++) {
401 		int sock_idx = args.single_sock ? 0 : i;
402 		sqe = io_uring_get_sqe(&m_io_uring);
403 		io_uring_prep_accept(sqe, fds[sock_idx], NULL, NULL, 0);
404 		sqe->user_data = 1 + i;
405 		ret = io_uring_submit(&m_io_uring);
406 		assert(ret == 1);
407 	}
408 
409 	if (args.usecs)
410 		usleep(args.usecs);
411 
412 	if (args.close_fds)
413 		for (i = 0; i < nr_socks; i++)
414 			close(fds[i]);
415 
416 	for (i = 0; i < nr; i++) {
417 		if (io_uring_peek_cqe(&m_io_uring, &cqe))
418 			break;
419 		if (cqe->res != -ECANCELED) {
420 			fprintf(stderr, "Expected cqe to be cancelled %d\n", cqe->res);
421 			ret = 1;
422 			goto out;
423 		}
424 		io_uring_cqe_seen(&m_io_uring, cqe);
425 	}
426 	ret = 0;
427 out:
428 	rlim.rlim_cur = cur_lim;
429 	if (setrlimit(RLIMIT_NPROC, &rlim) < 0) {
430 		perror("setrlimit");
431 		return 1;
432 	}
433 
434 	free(fds);
435 	io_uring_queue_exit(&m_io_uring);
436 	return ret;
437 }
438 
test_accept_cancel(unsigned usecs,unsigned int nr,bool multishot)439 static int test_accept_cancel(unsigned usecs, unsigned int nr, bool multishot)
440 {
441 	struct io_uring m_io_uring;
442 	struct io_uring_cqe *cqe;
443 	struct io_uring_sqe *sqe;
444 	int fd, i, ret;
445 
446 	if (multishot && no_accept_multi)
447 		return 0;
448 
449 	ret = io_uring_queue_init(32, &m_io_uring, 0);
450 	assert(ret >= 0);
451 
452 	fd = start_accept_listen(NULL, 0, 0);
453 
454 	for (i = 1; i <= nr; i++) {
455 		sqe = io_uring_get_sqe(&m_io_uring);
456 		if (!multishot)
457 			io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
458 		else
459 			io_uring_prep_multishot_accept(sqe, fd, NULL, NULL, 0);
460 		sqe->user_data = i;
461 		ret = io_uring_submit(&m_io_uring);
462 		assert(ret == 1);
463 	}
464 
465 	if (usecs)
466 		usleep(usecs);
467 
468 	for (i = 1; i <= nr; i++) {
469 		sqe = io_uring_get_sqe(&m_io_uring);
470 		io_uring_prep_cancel64(sqe, i, 0);
471 		sqe->user_data = nr + i;
472 		ret = io_uring_submit(&m_io_uring);
473 		assert(ret == 1);
474 	}
475 	for (i = 0; i < nr * 2; i++) {
476 		ret = io_uring_wait_cqe(&m_io_uring, &cqe);
477 		assert(!ret);
478 		/*
479 		 * Two cases here:
480 		 *
481 		 * 1) We cancel the accept4() before it got started, we should
482 		 *    get '0' for the cancel request and '-ECANCELED' for the
483 		 *    accept request.
484 		 * 2) We cancel the accept4() after it's already running, we
485 		 *    should get '-EALREADY' for the cancel request and
486 		 *    '-EINTR' for the accept request.
487 		 */
488 		if (cqe->user_data == 0) {
489 			fprintf(stderr, "unexpected 0 user data\n");
490 			goto err;
491 		} else if (cqe->user_data <= nr) {
492 			if (cqe->res != -EINTR && cqe->res != -ECANCELED) {
493 				fprintf(stderr, "Cancelled accept got %d\n", cqe->res);
494 				goto err;
495 			}
496 		} else if (cqe->user_data <= nr * 2) {
497 			if (cqe->res != -EALREADY && cqe->res != 0) {
498 				fprintf(stderr, "Cancel got %d\n", cqe->res);
499 				goto err;
500 			}
501 		}
502 		io_uring_cqe_seen(&m_io_uring, cqe);
503 	}
504 
505 	io_uring_queue_exit(&m_io_uring);
506 	close(fd);
507 	return 0;
508 err:
509 	io_uring_queue_exit(&m_io_uring);
510 	close(fd);
511 	return 1;
512 }
513 
test_accept(int count,bool before)514 static int test_accept(int count, bool before)
515 {
516 	struct io_uring m_io_uring;
517 	int ret;
518 	struct accept_test_args args = {
519 		.queue_accept_before_connect = before,
520 		.extra_loops = count - 1
521 	};
522 
523 	ret = io_uring_queue_init(32, &m_io_uring, 0);
524 	assert(ret >= 0);
525 	ret = test(&m_io_uring, args);
526 	io_uring_queue_exit(&m_io_uring);
527 	return ret;
528 }
529 
test_multishot_accept(int count,bool before)530 static int test_multishot_accept(int count, bool before)
531 {
532 	struct io_uring m_io_uring;
533 	int ret;
534 	struct accept_test_args args = {
535 		.queue_accept_before_connect = before,
536 		.multishot = true,
537 		.extra_loops = count - 1
538 	};
539 
540 	if (no_accept_multi)
541 		return 0;
542 
543 	ret = io_uring_queue_init(MAX_FDS + 10, &m_io_uring, 0);
544 	assert(ret >= 0);
545 	ret = test(&m_io_uring, args);
546 	io_uring_queue_exit(&m_io_uring);
547 	return ret;
548 }
549 
test_accept_multishot_wrong_arg()550 static int test_accept_multishot_wrong_arg()
551 {
552 	struct io_uring m_io_uring;
553 	struct io_uring_cqe *cqe;
554 	struct io_uring_sqe *sqe;
555 	int fd, ret;
556 
557 	ret = io_uring_queue_init(4, &m_io_uring, 0);
558 	assert(ret >= 0);
559 
560 	fd = start_accept_listen(NULL, 0, 0);
561 
562 	sqe = io_uring_get_sqe(&m_io_uring);
563 	io_uring_prep_multishot_accept_direct(sqe, fd, NULL, NULL, 0);
564 	sqe->file_index = 1;
565 	ret = io_uring_submit(&m_io_uring);
566 	assert(ret == 1);
567 
568 	ret = io_uring_wait_cqe(&m_io_uring, &cqe);
569 	assert(!ret);
570 	if (cqe->res != -EINVAL) {
571 		fprintf(stderr, "file index should be IORING_FILE_INDEX_ALLOC \
572 				if its accept in multishot direct mode\n");
573 		goto err;
574 	}
575 	io_uring_cqe_seen(&m_io_uring, cqe);
576 
577 	io_uring_queue_exit(&m_io_uring);
578 	close(fd);
579 	return 0;
580 err:
581 	io_uring_queue_exit(&m_io_uring);
582 	close(fd);
583 	return 1;
584 }
585 
586 
test_accept_nonblock(bool queue_before_connect,int count)587 static int test_accept_nonblock(bool queue_before_connect, int count)
588 {
589 	struct io_uring m_io_uring;
590 	int ret;
591 	struct accept_test_args args = {
592 		.nonblock = true,
593 		.queue_accept_before_connect = queue_before_connect,
594 		.extra_loops = count - 1
595 	};
596 
597 	ret = io_uring_queue_init(32, &m_io_uring, 0);
598 	assert(ret >= 0);
599 	ret = test(&m_io_uring, args);
600 	io_uring_queue_exit(&m_io_uring);
601 	return ret;
602 }
603 
test_accept_fixed(void)604 static int test_accept_fixed(void)
605 {
606 	struct io_uring m_io_uring;
607 	int ret, fd = -1;
608 	struct accept_test_args args = {
609 		.fixed = true
610 	};
611 
612 	ret = io_uring_queue_init(32, &m_io_uring, 0);
613 	assert(ret >= 0);
614 	ret = io_uring_register_files(&m_io_uring, &fd, 1);
615 	assert(ret == 0);
616 	ret = test(&m_io_uring, args);
617 	io_uring_queue_exit(&m_io_uring);
618 	return ret;
619 }
620 
test_multishot_fixed_accept(void)621 static int test_multishot_fixed_accept(void)
622 {
623 	struct io_uring m_io_uring;
624 	int ret, fd[MAX_FDS];
625 	struct accept_test_args args = {
626 		.fixed = true,
627 		.multishot = true
628 	};
629 
630 	if (no_accept_multi)
631 		return 0;
632 
633 	memset(fd, -1, sizeof(fd));
634 	ret = io_uring_queue_init(MAX_FDS + 10, &m_io_uring, 0);
635 	assert(ret >= 0);
636 	ret = io_uring_register_files(&m_io_uring, fd, MAX_FDS);
637 	assert(ret == 0);
638 	ret = test(&m_io_uring, args);
639 	io_uring_queue_exit(&m_io_uring);
640 	return ret;
641 }
642 
test_accept_sqpoll(void)643 static int test_accept_sqpoll(void)
644 {
645 	struct io_uring m_io_uring;
646 	struct io_uring_params p = { };
647 	int ret;
648 	struct accept_test_args args = { };
649 
650 	p.flags = IORING_SETUP_SQPOLL;
651 	ret = t_create_ring_params(32, &m_io_uring, &p);
652 	if (ret == T_SETUP_SKIP)
653 		return 0;
654 	else if (ret < 0)
655 		return ret;
656 
657 	args.accept_should_error = 1;
658 	if (p.features & IORING_FEAT_SQPOLL_NONFIXED)
659 		args.accept_should_error = 0;
660 
661 	ret = test(&m_io_uring, args);
662 	io_uring_queue_exit(&m_io_uring);
663 	return ret;
664 }
665 
main(int argc,char * argv[])666 int main(int argc, char *argv[])
667 {
668 	int ret;
669 
670 	if (argc > 1)
671 		return 0;
672 	ret = test_accept(1, false);
673 	if (ret) {
674 		fprintf(stderr, "test_accept failed\n");
675 		return ret;
676 	}
677 	if (no_accept)
678 		return 0;
679 
680 	ret = test_accept(2, false);
681 	if (ret) {
682 		fprintf(stderr, "test_accept(2) failed\n");
683 		return ret;
684 	}
685 
686 	ret = test_accept(2, true);
687 	if (ret) {
688 		fprintf(stderr, "test_accept(2, true) failed\n");
689 		return ret;
690 	}
691 
692 	ret = test_accept_nonblock(false, 1);
693 	if (ret) {
694 		fprintf(stderr, "test_accept_nonblock failed\n");
695 		return ret;
696 	}
697 
698 	ret = test_accept_nonblock(true, 1);
699 	if (ret) {
700 		fprintf(stderr, "test_accept_nonblock(before, 1) failed\n");
701 		return ret;
702 	}
703 
704 	ret = test_accept_nonblock(true, 3);
705 	if (ret) {
706 		fprintf(stderr, "test_accept_nonblock(before,3) failed\n");
707 		return ret;
708 	}
709 
710 	ret = test_accept_fixed();
711 	if (ret) {
712 		fprintf(stderr, "test_accept_fixed failed\n");
713 		return ret;
714 	}
715 
716 	ret = test_multishot_fixed_accept();
717 	if (ret) {
718 		fprintf(stderr, "test_multishot_fixed_accept failed\n");
719 		return ret;
720 	}
721 
722 	ret = test_accept_multishot_wrong_arg();
723 	if (ret) {
724 		fprintf(stderr, "test_accept_multishot_wrong_arg failed\n");
725 		return ret;
726 	}
727 
728 	ret = test_accept_sqpoll();
729 	if (ret) {
730 		fprintf(stderr, "test_accept_sqpoll failed\n");
731 		return ret;
732 	}
733 
734 	ret = test_accept_cancel(0, 1, false);
735 	if (ret) {
736 		fprintf(stderr, "test_accept_cancel nodelay failed\n");
737 		return ret;
738 	}
739 
740 	ret = test_accept_cancel(10000, 1, false);
741 	if (ret) {
742 		fprintf(stderr, "test_accept_cancel delay failed\n");
743 		return ret;
744 	}
745 
746 	ret = test_accept_cancel(0, 4, false);
747 	if (ret) {
748 		fprintf(stderr, "test_accept_cancel nodelay failed\n");
749 		return ret;
750 	}
751 
752 	ret = test_accept_cancel(10000, 4, false);
753 	if (ret) {
754 		fprintf(stderr, "test_accept_cancel delay failed\n");
755 		return ret;
756 	}
757 
758 	ret = test_accept_cancel(0, 1, true);
759 	if (ret) {
760 		fprintf(stderr, "test_accept_cancel multishot nodelay failed\n");
761 		return ret;
762 	}
763 
764 	ret = test_accept_cancel(10000, 1, true);
765 	if (ret) {
766 		fprintf(stderr, "test_accept_cancel multishot delay failed\n");
767 		return ret;
768 	}
769 
770 	ret = test_accept_cancel(0, 4, true);
771 	if (ret) {
772 		fprintf(stderr, "test_accept_cancel multishot nodelay failed\n");
773 		return ret;
774 	}
775 
776 	ret = test_accept_cancel(10000, 4, true);
777 	if (ret) {
778 		fprintf(stderr, "test_accept_cancel multishot delay failed\n");
779 		return ret;
780 	}
781 
782 	ret = test_multishot_accept(1, false);
783 	if (ret) {
784 		fprintf(stderr, "test_multishot_accept(1, false) failed\n");
785 		return ret;
786 	}
787 
788 	ret = test_multishot_accept(1, true);
789 	if (ret) {
790 		fprintf(stderr, "test_multishot_accept(1, true) failed\n");
791 		return ret;
792 	}
793 
794 	ret = test_accept_many((struct test_accept_many_args) {});
795 	if (ret) {
796 		fprintf(stderr, "test_accept_many failed\n");
797 		return ret;
798 	}
799 
800 	ret = test_accept_many((struct test_accept_many_args) {
801 				.usecs = 100000 });
802 	if (ret) {
803 		fprintf(stderr, "test_accept_many(sleep) failed\n");
804 		return ret;
805 	}
806 
807 	ret = test_accept_many((struct test_accept_many_args) {
808 				.nonblock = true });
809 	if (ret) {
810 		fprintf(stderr, "test_accept_many(nonblock) failed\n");
811 		return ret;
812 	}
813 
814 	ret = test_accept_many((struct test_accept_many_args) {
815 				.nonblock = true,
816 				.single_sock = true,
817 				.close_fds = true });
818 	if (ret) {
819 		fprintf(stderr, "test_accept_many(nonblock,close) failed\n");
820 		return ret;
821 	}
822 
823 	ret = test_accept_pending_on_exit();
824 	if (ret) {
825 		fprintf(stderr, "test_accept_pending_on_exit failed\n");
826 		return ret;
827 	}
828 	return 0;
829 }
830