From 55196ee2a0430d920ea7a2c89a6e322615f78334 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Wed, 7 Aug 2024 12:04:52 +0200 Subject: [PATCH] Replace pselect with a 64-bit-time_t wrapper Part of #10634 --- src/input_common.rs | 21 ++++++++++----------- src/libc.c | 17 +++++++++++++++++ src/libc.rs | 28 ++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/input_common.rs b/src/input_common.rs index fc9ece828..425e65f1c 100644 --- a/src/input_common.rs +++ b/src/input_common.rs @@ -11,6 +11,7 @@ self, alt, canonicalize_control_char, canonicalize_keyed_control_char, function_key, shift, Key, Modifiers, }; +use crate::libc::{pselect64, timespec64}; use crate::reader::{reader_current_data, reader_test_and_clear_interrupted}; use crate::threads::{iothread_port, MainThread}; use crate::universal_notifier::default_notifier; @@ -1080,7 +1081,7 @@ fn readch_timed(&mut self, wait_time_ms: usize) -> Option { const NSEC_PER_MSEC: u64 = 1000 * 1000; const NSEC_PER_SEC: u64 = NSEC_PER_MSEC * 1000; let wait_nsec: u64 = (wait_time_ms as u64) * NSEC_PER_MSEC; - let timeout = libc::timespec { + let timeout = timespec64 { tv_sec: (wait_nsec / NSEC_PER_SEC).try_into().unwrap(), tv_nsec: (wait_nsec % NSEC_PER_SEC).try_into().unwrap(), }; @@ -1092,16 +1093,14 @@ fn readch_timed(&mut self, wait_time_ms: usize) -> Option { libc::FD_ZERO(&mut fdset); libc::FD_SET(in_fd, &mut fdset); }; - let res = unsafe { - libc::pselect( - in_fd + 1, - &mut fdset, - ptr::null_mut(), - ptr::null_mut(), - &timeout, - &sigs, - ) - }; + let res = pselect64( + in_fd + 1, + &mut fdset, + ptr::null_mut(), + ptr::null_mut(), + &timeout, + &sigs, + ); // Prevent signal starvation on WSL causing the `torn_escapes.py` test to fail if is_windows_subsystem_for_linux(WSL::V1) { diff --git a/src/libc.c b/src/libc.c index c162f0fd2..d35244857 100644 --- a/src/libc.c +++ b/src/libc.c @@ -250,6 +250,23 @@ int C_select64(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, return result; } +struct timespec64 { + int64_t tv_sec; + int64_t tv_nsec; +}; + +int C_pselect64(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, + struct timespec64* timeout64, const sigset_t* sigmask) { + struct timespec timeout; + if (timeout64) { + timeout.tv_sec = timeout64->tv_sec; + timeout.tv_nsec = timeout64->tv_nsec; + assert_or_die(timeout.tv_sec == timeout64->tv_sec); + assert_or_die(timeout.tv_nsec == timeout64->tv_nsec); + } + return pselect(nfds, readfds, writefds, errorfds, timeout64 ? &timeout : NULL, sigmask); +} + struct rusage64 { struct timeval64 ru_utime; struct timeval64 ru_stime; diff --git a/src/libc.rs b/src/libc.rs index 3d9ad3caf..75ad254d2 100644 --- a/src/libc.rs +++ b/src/libc.rs @@ -150,6 +150,34 @@ fn C_select64( ) -> c_int; } +#[repr(C)] +#[derive(Clone, Copy)] +pub struct timespec64 { + pub tv_sec: i64, + pub tv_nsec: i64, +} + +pub(crate) fn pselect64( + nfds: c_int, + readfds: *mut fd_set, + writefds: *mut fd_set, + errorfds: *mut fd_set, + timeout: *const timespec64, + sigmask: *const libc::sigset_t, +) -> c_int { + unsafe { C_pselect64(nfds, readfds, writefds, errorfds, timeout, sigmask) } +} +extern "C" { + fn C_pselect64( + nfds: c_int, + readfds: *mut fd_set, + writefds: *mut fd_set, + errorfds: *mut fd_set, + timeout: *const timespec64, + sigmask: *const libc::sigset_t, + ) -> c_int; +} + #[repr(C)] pub struct rusage64 { pub ru_utime: timeval64,