diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2021-06-15 21:00:50 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2021-06-22 12:09:52 -0300 |
commit | 4c3df0eba5e8fe98f0de917ade9b2ebba6951c5f (patch) | |
tree | 137a7ae34464f27fa19029863d4f6f06860e3150 /misc/tst-select.c | |
parent | 91cf411ad3ef10bd18ec053854fcb919be4f6789 (diff) | |
download | glibc-4c3df0eba5e8fe98f0de917ade9b2ebba6951c5f.tar.gz glibc-4c3df0eba5e8fe98f0de917ade9b2ebba6951c5f.tar.xz glibc-4c3df0eba5e8fe98f0de917ade9b2ebba6951c5f.zip |
linux: Only use 64-bit syscall if required for select
For !__ASSUME_TIME64_SYSCALLS there is no need to issue a 64-bit syscall if the provided timeout fits in a 32-bit one. The 64-bit usage should be rare since the timeout is a relative one. This also avoids the need to use supports_time64() (which breaks the usage case of live migration like CRIU or similar). It also fixes an issue on 32-bit select call for !__ASSUME_PSELECT (microblase with older kernels only) where the expected timeout is a 'struct timeval' instead of 'struct timespec'. Checked on i686-linux-gnu on a 4.15 kernel and on a 5.11 kernel (with and without --enable-kernel=5.1) and on x86_64-linux-gnu. Reviewed-by: Lukasz Majewski <lukma@denx.de>
Diffstat (limited to 'misc/tst-select.c')
-rw-r--r-- | misc/tst-select.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/misc/tst-select.c b/misc/tst-select.c index 52aa26651f..134eed99be 100644 --- a/misc/tst-select.c +++ b/misc/tst-select.c @@ -17,6 +17,7 @@ <https://www.gnu.org/licenses/>. */ #include <errno.h> +#include <intprops.h> #include <support/capture_subprocess.h> #include <support/check.h> #include <support/support.h> @@ -32,12 +33,6 @@ struct child_args }; static void -alarm_handler (int signum) -{ - /* Do nothing. */ -} - -static void do_test_child (void *clousure) { struct child_args *args = (struct child_args *) clousure; @@ -69,17 +64,20 @@ do_test_child (void *clousure) static void do_test_child_alarm (void *clousure) { - struct sigaction act = { .sa_handler = alarm_handler }; - xsigaction (SIGALRM, &act, NULL); - alarm (1); + struct child_args *args = (struct child_args *) clousure; - struct timeval tv = { .tv_sec = 10, .tv_usec = 0 }; + support_create_timer (0, 100000000, false, NULL); + struct timeval tv = { .tv_sec = args->tmo.tv_sec, .tv_usec = 0 }; int r = select (0, NULL, NULL, NULL, &tv); TEST_COMPARE (r, -1); - TEST_COMPARE (errno, EINTR); - - if (support_select_modifies_timeout ()) - TEST_VERIFY (tv.tv_sec < 10); + if (args->tmo.tv_sec > INT_MAX) + TEST_VERIFY (errno == EINTR || errno == EOVERFLOW); + else + { + TEST_COMPARE (errno, EINTR); + if (support_select_modifies_timeout ()) + TEST_VERIFY (tv.tv_sec < args->tmo.tv_sec); + } } static int @@ -121,13 +119,24 @@ do_test (void) xclose (args.fds[0][0]); xclose (args.fds[1][1]); + args.tmo = (struct timeval) { .tv_sec = 10, .tv_usec = 0 }; + { + struct support_capture_subprocess result; + result = support_capture_subprocess (do_test_child_alarm, &args); + support_capture_subprocess_check (&result, "tst-select-child", 0, + sc_allow_none); + } + + args.tmo = (struct timeval) { .tv_sec = TYPE_MAXIMUM (time_t), + .tv_usec = 0 }; { struct support_capture_subprocess result; - result = support_capture_subprocess (do_test_child_alarm, NULL); + result = support_capture_subprocess (do_test_child_alarm, &args); support_capture_subprocess_check (&result, "tst-select-child", 0, sc_allow_none); } + args.tmo = (struct timeval) { .tv_sec = 0, .tv_usec = 0 }; { fd_set rfds; FD_ZERO (&rfds); |