mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 13:23:09 +00:00
7b7d16da48
This was based on a misunderstanding. On musl, 64-bit time_t on 32-bit architectures was introduced in version 1.2.0, by introducing new symbols. The old symbols still exist, to allow programs compiled against older versions to keep running on 1.2.0+, preserving ABI-compatibility. (see musl commit 38143339646a4ccce8afe298c34467767c899f51) Programs compiled against 1.2.0+ will get the new symbols, and will therefore think time_t is 64-bit. Unfortunately, rust's libc crate uses its own definition of these types, and does not check for musl version. Currently, it includes the pre-1.2.0 32-bit type. That means: - If you run on a 32-bit system like i686 - ... and compile against a C-library other than libc - ... and pass it a time_t-containing struct like timespec or stat ... you need to arrange for that library to be built against musl <1.2.0. Or, as https://github.com/ericonr/rust-time64 says: > Therefore, for "old" 32-bit targets (riscv32 is supposed to default to time64), > any Rust code that interacts with C code built on musl after 1.2.0, > using types based on time_t (arguably, the main ones are struct timespec and struct stat) in their interface, > will be completely miscompiled. However, while fish runs on i686 and compiles against pcre2, we do not pass pcre2 a time_t. Our only uses of time_t are confined to interactions with libc, in which case with musl we would simply use the legacy ABI. I have compiled an i686 fish against musl to confirm and can find no issue. This reverts commit55196ee2a0
. This reverts commit4992f88966
. This reverts commit46c8ba2c9f
. This reverts commit3a9b4149da
. This reverts commit5f9e9cbe74
. This reverts commit338579b78c
. This reverts commitd19e5508d7
. This reverts commitb64045dc18
. Closes #10634
39 lines
1 KiB
Rust
39 lines
1 KiB
Rust
//! Safe wrappers around various libc functions that we might want to reuse across modules.
|
|
|
|
use std::time::Duration;
|
|
|
|
#[allow(clippy::unnecessary_cast)]
|
|
pub const fn timeval_to_duration(val: &libc::timeval) -> Duration {
|
|
let micros = val.tv_sec as i64 * (1E6 as i64) + val.tv_usec as i64;
|
|
Duration::from_micros(micros as u64)
|
|
}
|
|
|
|
pub trait TimevalExt {
|
|
fn as_micros(&self) -> i64;
|
|
fn as_duration(&self) -> Duration;
|
|
}
|
|
|
|
impl TimevalExt for libc::timeval {
|
|
fn as_micros(&self) -> i64 {
|
|
timeval_to_duration(self).as_micros() as i64
|
|
}
|
|
|
|
fn as_duration(&self) -> Duration {
|
|
timeval_to_duration(self)
|
|
}
|
|
}
|
|
|
|
pub fn geteuid() -> u32 {
|
|
unsafe { libc::geteuid() }
|
|
}
|
|
pub fn getegid() -> u32 {
|
|
unsafe { libc::getegid() }
|
|
}
|
|
pub fn getpid() -> i32 {
|
|
unsafe { libc::getpid() }
|
|
}
|
|
pub fn isatty(fd: i32) -> bool {
|
|
// This returns false if the fd is valid but not a tty, or is invalid.
|
|
// No place we currently call it really cares about the difference.
|
|
return unsafe { libc::isatty(fd) } == 1;
|
|
}
|