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/>. */
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>
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]);
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
);
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);
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
);
73 if (args
->tmo
.tv_sec
> INT_MAX
)
74 TEST_VERIFY (errno
== EINTR
|| errno
== EOVERFLOW
);
77 TEST_COMPARE (errno
, EINTR
);
78 if (support_select_modifies_timeout ())
79 TEST_VERIFY (tv
.tv_sec
< args
->tmo
.tv_sec
);
86 struct child_args args
;
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,
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,
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,
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,
130 args
.tmo
= (struct timeval
) { .tv_sec
= TYPE_MAXIMUM (time_t),
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,
139 args
.tmo
= (struct timeval
) { .tv_sec
= 0, .tv_usec
= 0 };
143 FD_SET (args
.fds
[1][0], &rfds
);
145 int r
= select (args
.fds
[1][0] + 1, &rfds
, NULL
, NULL
, &args
.tmo
);
152 #include <support/test-driver.c>