• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2020 Linaro Limited. All rights reserved.
4  * Author: Viresh Kumar <viresh.kumar@linaro.org>
5  */
6 
7 /*\
8  * [Description]
9  *
10  * Test to check if fd set bits are cleared by select().
11  *
12  * [Algorithm]
13  *  - Check that writefds flag is cleared on full pipe
14  *  - Check that readfds flag is cleared on empty pipe
15  */
16 
17 #include <unistd.h>
18 #include <errno.h>
19 #include <sys/time.h>
20 #include <sys/types.h>
21 #include <fcntl.h>
22 #include "select_var.h"
23 
24 static fd_set readfds_pipe, writefds_pipe;
25 static int fd_empty[2], fd_full[2];
26 
27 static struct tcases {
28 	int *fd;
29 	fd_set *readfds;
30 	fd_set *writefds;
31 	char *desc;
32 } tests[] = {
33 	{&fd_empty[0], &readfds_pipe, NULL, "No data to read"},
34 	{&fd_full[1], NULL, &writefds_pipe, "No space to write"},
35 };
36 
run(unsigned int n)37 static void run(unsigned int n)
38 {
39 	struct tcases *tc = &tests[n];
40 	struct timeval timeout = {.tv_sec = 0, .tv_usec = 1000};
41 
42 	FD_SET(fd_empty[0], &readfds_pipe);
43 	FD_SET(fd_full[1], &writefds_pipe);
44 
45 	TEST(do_select(*tc->fd + 1, tc->readfds, tc->writefds, NULL, &timeout));
46 
47 	if (TST_RET) {
48 		tst_res(TFAIL, "%s: select() should have timed out", tc->desc);
49 		return;
50 	}
51 
52 	if ((tc->readfds && FD_ISSET(*tc->fd, tc->readfds)) ||
53 	    (tc->writefds && FD_ISSET(*tc->fd, tc->writefds))) {
54 		tst_res(TFAIL, "%s: select() didn't clear the fd set", tc->desc);
55 		return;
56 	}
57 
58 	tst_res(TPASS, "%s: select() cleared the fd set", tc->desc);
59 }
60 
setup(void)61 static void setup(void)
62 {
63 	int buf = 0;
64 
65 	select_info();
66 
67 	SAFE_PIPE(fd_empty);
68 	FD_ZERO(&readfds_pipe);
69 
70 	SAFE_PIPE2(fd_full, O_NONBLOCK);
71 	FD_ZERO(&writefds_pipe);
72 
73 	/* Make the write buffer full for fd_full */
74 	do {
75 		TEST(write(fd_full[1], &buf, sizeof(buf)));
76 	} while (TST_RET != -1);
77 
78 	if (TST_ERR != EAGAIN)
79 		tst_res(TFAIL | TTERRNO, "write() failed with unexpected error");
80 }
81 
82 static struct tst_test test = {
83 	.test = run,
84 	.tcnt = ARRAY_SIZE(tests),
85 	.test_variants = TEST_VARIANTS,
86 	.setup = setup,
87 	.needs_tmpdir = 1,
88 };
89