1 /* Test for select timeout.
2 Copyright (C) 2021 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/>. */
20 #include <support/capture_subprocess.h>
21 #include <support/check.h>
22 #include <support/support.h>
23 #include <support/timespec.h>
24 #include <support/xunistd.h>
25 #include <support/xtime.h>
26 #include <support/xsignal.h>
35 alarm_handler (int signum
)
41 do_test_child (void *clousure
)
43 struct child_args
*args
= (struct child_args
*) clousure
;
45 close (args
->fds
[0][1]);
46 close (args
->fds
[1][0]);
50 FD_SET (args
->fds
[0][0], &rfds
);
52 struct timespec ts
= xclock_now (CLOCK_REALTIME
);
53 ts
= timespec_add (ts
, (struct timespec
) { args
->tmo
.tv_sec
, 0 });
55 int r
= select (args
->fds
[0][0] + 1, &rfds
, NULL
, NULL
, &args
->tmo
);
58 if (support_select_modifies_timeout ())
60 TEST_COMPARE (args
->tmo
.tv_sec
, 0);
61 TEST_COMPARE (args
->tmo
.tv_usec
, 0);
64 TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME
, ts
);
66 xwrite (args
->fds
[1][1], "foo", 3);
70 do_test_child_alarm (void *clousure
)
72 struct sigaction act
= { .sa_handler
= alarm_handler
};
73 xsigaction (SIGALRM
, &act
, NULL
);
76 struct timeval tv
= { .tv_sec
= 10, .tv_usec
= 0 };
77 int r
= select (0, NULL
, NULL
, NULL
, &tv
);
79 TEST_COMPARE (errno
, EINTR
);
81 if (support_select_modifies_timeout ())
82 TEST_VERIFY (tv
.tv_sec
< 10);
88 struct child_args args
;
93 /* The child select should timeout and write on its pipe end. */
94 args
.tmo
= (struct timeval
) { .tv_sec
= 0, .tv_usec
= 250000 };
96 struct support_capture_subprocess result
;
97 result
= support_capture_subprocess (do_test_child
, &args
);
98 support_capture_subprocess_check (&result
, "tst-select-child", 0,
102 if (support_select_normalizes_timeout ())
104 /* This is handled as 1 second instead of failing with EINVAL. */
105 args
.tmo
= (struct timeval
) { .tv_sec
= 0, .tv_usec
= 1000000 };
106 struct support_capture_subprocess result
;
107 result
= support_capture_subprocess (do_test_child
, &args
);
108 support_capture_subprocess_check (&result
, "tst-select-child", 0,
112 /* Same as before, but simulating polling. */
113 args
.tmo
= (struct timeval
) { .tv_sec
= 0, .tv_usec
= 0 };
115 struct support_capture_subprocess result
;
116 result
= support_capture_subprocess (do_test_child
, &args
);
117 support_capture_subprocess_check (&result
, "tst-select-child", 0,
121 xclose (args
.fds
[0][0]);
122 xclose (args
.fds
[1][1]);
125 struct support_capture_subprocess result
;
126 result
= support_capture_subprocess (do_test_child_alarm
, NULL
);
127 support_capture_subprocess_check (&result
, "tst-select-child", 0,
134 FD_SET (args
.fds
[1][0], &rfds
);
136 int r
= select (args
.fds
[1][0] + 1, &rfds
, NULL
, NULL
, &args
.tmo
);
143 #include <support/test-driver.c>