fish-shell/src/nix.rs

40 lines
1.0 KiB
Rust
Raw Normal View History

2023-02-15 05:54:18 +08:00
//! Safe wrappers around various libc functions that we might want to reuse across modules.
use std::time::Duration;
Revert libc time_t changes 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 commit 55196ee2a0430d920ea7a2c89a6e322615f78334. This reverts commit 4992f8896633fb8ca8d89e09f02330cd49395485. This reverts commit 46c8ba2c9fec77195091ddcf7ee0bb3d9a6e5f54. This reverts commit 3a9b4149da7d44b8648702f17d9e9eef651e56f9. This reverts commit 5f9e9cbe741025231acfb24dc900433e1c6738ac. This reverts commit 338579b78ca2ba0aab108304bc33a53fddeb11ba. This reverts commit d19e5508d7b406da6813edb9d0a6909094d20e5a. This reverts commit b64045dc189ec58b6bd3dea71e1441e00876904c. Closes #10634
2024-08-27 17:15:27 +08:00
#[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;
2023-02-15 05:54:18 +08:00
Duration::from_micros(micros as u64)
}
pub trait TimevalExt {
fn as_micros(&self) -> i64;
fn as_duration(&self) -> Duration;
}
Revert libc time_t changes 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 commit 55196ee2a0430d920ea7a2c89a6e322615f78334. This reverts commit 4992f8896633fb8ca8d89e09f02330cd49395485. This reverts commit 46c8ba2c9fec77195091ddcf7ee0bb3d9a6e5f54. This reverts commit 3a9b4149da7d44b8648702f17d9e9eef651e56f9. This reverts commit 5f9e9cbe741025231acfb24dc900433e1c6738ac. This reverts commit 338579b78ca2ba0aab108304bc33a53fddeb11ba. This reverts commit d19e5508d7b406da6813edb9d0a6909094d20e5a. This reverts commit b64045dc189ec58b6bd3dea71e1441e00876904c. Closes #10634
2024-08-27 17:15:27 +08:00
impl TimevalExt for libc::timeval {
2023-02-15 05:54:18 +08:00
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;
}