mirror of
https://github.com/fish-shell/fish-shell
synced 2024-11-10 07:04:29 +00:00
parent
3a9b4149da
commit
46c8ba2c9f
4 changed files with 76 additions and 20 deletions
|
@ -7,6 +7,7 @@ use crate::common::exit_without_destructors;
|
|||
use crate::fd_readable_set::FdReadableSet;
|
||||
use crate::fds::AutoCloseFd;
|
||||
use crate::flog::FLOG;
|
||||
use crate::libc::{select64, timeval64};
|
||||
use crate::threads::assert_is_background_thread;
|
||||
use crate::wutil::perror;
|
||||
use errno::errno;
|
||||
|
@ -142,26 +143,24 @@ impl FdEventSignaller {
|
|||
/// but guarantees that the next call to wait() will not block.
|
||||
/// Return true if readable, false if not readable, or not interrupted by a signal.
|
||||
pub fn poll(&self, wait: bool /* = false */) -> bool {
|
||||
let mut timeout = libc::timeval {
|
||||
let mut timeout = timeval64 {
|
||||
tv_sec: 0,
|
||||
tv_usec: 0,
|
||||
};
|
||||
let mut fds: libc::fd_set = unsafe { std::mem::zeroed() };
|
||||
unsafe { libc::FD_ZERO(&mut fds) };
|
||||
unsafe { libc::FD_SET(self.read_fd(), &mut fds) };
|
||||
let res = unsafe {
|
||||
libc::select(
|
||||
self.read_fd() + 1,
|
||||
&mut fds,
|
||||
std::ptr::null_mut(),
|
||||
std::ptr::null_mut(),
|
||||
if wait {
|
||||
std::ptr::null_mut()
|
||||
} else {
|
||||
&mut timeout
|
||||
},
|
||||
)
|
||||
};
|
||||
let res = select64(
|
||||
self.read_fd() + 1,
|
||||
&mut fds,
|
||||
std::ptr::null_mut(),
|
||||
std::ptr::null_mut(),
|
||||
if wait {
|
||||
std::ptr::null_mut()
|
||||
} else {
|
||||
&mut timeout
|
||||
},
|
||||
);
|
||||
res > 0
|
||||
}
|
||||
|
||||
|
|
|
@ -68,9 +68,10 @@ impl FdReadableSet {
|
|||
/// destructively modifies the set. Returns the result of `select()` or `poll()`.
|
||||
pub fn check_readable(&mut self, timeout_usec: u64) -> c_int {
|
||||
let null = std::ptr::null_mut();
|
||||
use crate::libc::{select64, timeval64};
|
||||
if timeout_usec == Self::kNoTimeout {
|
||||
unsafe {
|
||||
return libc::select(
|
||||
return select64(
|
||||
self.nfds_,
|
||||
&mut self.fdset_,
|
||||
null,
|
||||
|
@ -79,12 +80,12 @@ impl FdReadableSet {
|
|||
);
|
||||
}
|
||||
} else {
|
||||
let mut tvs = libc::timeval {
|
||||
tv_sec: (timeout_usec / kUsecPerSec) as libc::time_t,
|
||||
tv_usec: (timeout_usec % kUsecPerSec) as libc::suseconds_t,
|
||||
let mut tvs = timeval64 {
|
||||
tv_sec: (timeout_usec / kUsecPerSec).try_into().unwrap(),
|
||||
tv_usec: (timeout_usec % kUsecPerSec).try_into().unwrap(),
|
||||
};
|
||||
unsafe {
|
||||
return libc::select(self.nfds_, &mut self.fdset_, null, null, &mut tvs);
|
||||
return select64(self.nfds_, &mut self.fdset_, null, null, &mut tvs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
30
src/libc.c
30
src/libc.c
|
@ -1,3 +1,4 @@
|
|||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <locale.h>
|
||||
|
@ -7,6 +8,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
@ -14,6 +16,12 @@
|
|||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
#define assert_or_die(x) \
|
||||
do { \
|
||||
assert((x)); \
|
||||
if (!(x)) abort(); \
|
||||
} while (false)
|
||||
|
||||
size_t C_MB_CUR_MAX() { return MB_CUR_MAX; }
|
||||
|
||||
uint64_t C_ST_LOCAL() {
|
||||
|
@ -219,3 +227,25 @@ bool C_localtime64_r(int64_t timep, struct tm* result) {
|
|||
time_t timep_ = timep;
|
||||
return localtime_r(&timep_, result);
|
||||
}
|
||||
|
||||
struct timeval64 {
|
||||
int64_t tv_sec;
|
||||
int64_t tv_usec;
|
||||
};
|
||||
|
||||
int C_select64(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds,
|
||||
struct timeval64* timeout64) {
|
||||
struct timeval timeout;
|
||||
if (timeout64) {
|
||||
timeout.tv_sec = timeout64->tv_sec;
|
||||
timeout.tv_usec = timeout64->tv_usec;
|
||||
assert_or_die(timeout.tv_sec == timeout64->tv_sec);
|
||||
assert_or_die(timeout.tv_usec == timeout64->tv_usec);
|
||||
}
|
||||
int result = select(nfds, readfds, writefds, errorfds, timeout64 ? &timeout : NULL);
|
||||
if (timeout64) {
|
||||
timeout64->tv_sec = timeout.tv_sec;
|
||||
timeout64->tv_usec = timeout.tv_usec;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
28
src/libc.rs
28
src/libc.rs
|
@ -1,6 +1,6 @@
|
|||
use std::{ffi::CStr, sync::atomic::AtomicPtr};
|
||||
|
||||
use libc::{c_char, c_int};
|
||||
use libc::{c_char, c_int, fd_set};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
pub static _PATH_BSHELL: AtomicPtr<c_char> = AtomicPtr::new(std::ptr::null_mut());
|
||||
|
@ -123,3 +123,29 @@ pub(crate) fn localtime64_r(timep: i64) -> Option<libc::tm> {
|
|||
extern "C" {
|
||||
fn C_localtime64_r(timep: i64, result: *mut libc::tm) -> bool;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) struct timeval64 {
|
||||
pub tv_sec: i64,
|
||||
pub tv_usec: i64,
|
||||
}
|
||||
|
||||
pub(crate) fn select64(
|
||||
nfds: c_int,
|
||||
readfds: *mut fd_set,
|
||||
writefds: *mut fd_set,
|
||||
errorfds: *mut fd_set,
|
||||
timeout: *mut timeval64,
|
||||
) -> c_int {
|
||||
unsafe { C_select64(nfds, readfds, writefds, errorfds, timeout) }
|
||||
}
|
||||
extern "C" {
|
||||
fn C_select64(
|
||||
nfds: c_int,
|
||||
readfds: *mut fd_set,
|
||||
writefds: *mut fd_set,
|
||||
errorfds: *mut fd_set,
|
||||
timeout: *mut timeval64,
|
||||
) -> c_int;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue