Refer to C23 in place of C2X in glibc
[glibc.git] / misc / tst-select.c
blob7b0994ea1f59459881df9918c713f8f32dab4978
1 /* Test for select timeout.
2 Copyright (C) 2021-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 #include <errno.h>
20 #include <intprops.h>
21 #include <support/capture_subprocess.h>
22 #include <support/check.h>
23 #include <support/support.h>
24 #include <support/timespec.h>
25 #include <support/xunistd.h>
26 #include <support/xtime.h>
27 #include <support/xsignal.h>
29 struct child_args
31 int fds[2][2];
32 struct timeval tmo;
35 static void
36 do_test_child (void *clousure)
38 struct child_args *args = (struct child_args *) clousure;
40 close (args->fds[0][1]);
41 close (args->fds[1][0]);
43 fd_set rfds;
44 FD_ZERO (&rfds);
45 FD_SET (args->fds[0][0], &rfds);
47 struct timespec ts = xclock_now (CLOCK_REALTIME);
48 ts = timespec_add (ts, (struct timespec) { args->tmo.tv_sec, 0 });
50 int r = select (args->fds[0][0] + 1, &rfds, NULL, NULL, &args->tmo);
51 TEST_COMPARE (r, 0);
53 if (support_select_modifies_timeout ())
55 TEST_COMPARE (args->tmo.tv_sec, 0);
56 TEST_COMPARE (args->tmo.tv_usec, 0);
59 TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts);
61 xwrite (args->fds[1][1], "foo", 3);
64 static void
65 do_test_child_alarm (void *clousure)
67 struct child_args *args = (struct child_args *) clousure;
69 support_create_timer (0, 100000000, false, NULL);
70 struct timeval tv = { .tv_sec = args->tmo.tv_sec, .tv_usec = 0 };
71 int r = select (0, NULL, NULL, NULL, &tv);
72 TEST_COMPARE (r, -1);
73 if (args->tmo.tv_sec > INT_MAX)
74 TEST_VERIFY (errno == EINTR || errno == EOVERFLOW);
75 else
77 TEST_COMPARE (errno, EINTR);
78 if (support_select_modifies_timeout ())
79 TEST_VERIFY (tv.tv_sec < args->tmo.tv_sec);
83 static int
84 do_test (void)
86 struct child_args args;
88 xpipe (args.fds[0]);
89 xpipe (args.fds[1]);
91 /* The child select should timeout and write on its pipe end. */
92 args.tmo = (struct timeval) { .tv_sec = 0, .tv_usec = 250000 };
94 struct support_capture_subprocess result;
95 result = support_capture_subprocess (do_test_child, &args);
96 support_capture_subprocess_check (&result, "tst-select-child", 0,
97 sc_allow_none);
100 if (support_select_normalizes_timeout ())
102 /* This is handled as 1 second instead of failing with EINVAL. */
103 args.tmo = (struct timeval) { .tv_sec = 0, .tv_usec = 1000000 };
104 struct support_capture_subprocess result;
105 result = support_capture_subprocess (do_test_child, &args);
106 support_capture_subprocess_check (&result, "tst-select-child", 0,
107 sc_allow_none);
110 /* Same as before, but simulating polling. */
111 args.tmo = (struct timeval) { .tv_sec = 0, .tv_usec = 0 };
113 struct support_capture_subprocess result;
114 result = support_capture_subprocess (do_test_child, &args);
115 support_capture_subprocess_check (&result, "tst-select-child", 0,
116 sc_allow_none);
119 xclose (args.fds[0][0]);
120 xclose (args.fds[1][1]);
122 args.tmo = (struct timeval) { .tv_sec = 10, .tv_usec = 0 };
124 struct support_capture_subprocess result;
125 result = support_capture_subprocess (do_test_child_alarm, &args);
126 support_capture_subprocess_check (&result, "tst-select-child", 0,
127 sc_allow_none);
130 args.tmo = (struct timeval) { .tv_sec = TYPE_MAXIMUM (time_t),
131 .tv_usec = 0 };
133 struct support_capture_subprocess result;
134 result = support_capture_subprocess (do_test_child_alarm, &args);
135 support_capture_subprocess_check (&result, "tst-select-child", 0,
136 sc_allow_none);
139 args.tmo = (struct timeval) { .tv_sec = 0, .tv_usec = 0 };
141 fd_set rfds;
142 FD_ZERO (&rfds);
143 FD_SET (args.fds[1][0], &rfds);
145 int r = select (args.fds[1][0] + 1, &rfds, NULL, NULL, &args.tmo);
146 TEST_COMPARE (r, 1);
149 return 0;
152 #include <support/test-driver.c>