diff --git a/Cargo.toml b/Cargo.toml index 0dafbd643..cff1c438f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,12 +35,12 @@ pcre2 = { git = "https://github.com/fish-shell/rust-pcre2", tag = "0.2.9-utf32", bitflags = "2.5.0" errno = "0.3.0" -libc = "0.2" +libc = { git = "https://github.com/rust-lang/libc", rev = "b31ee9b22f99354f2ca00c68d038d6f377c8b8a4", features = ["extra_traits"] } # lru pulls in hashbrown by default, which uses a faster (though less DoS resistant) hashing algo. # disabling default features uses the stdlib instead, but it doubles the time to rewrite the history # files as of 22 April 2024. lru = "0.13.0" -nix = { version = "0.30.1", default-features = false, features = [ +nix = { git = "https://github.com/joshuamegnauth54/nix", branch = "redox-fish-no-merge", default-features = false, features = [ "event", "inotify", "resource", diff --git a/build.rs b/build.rs index 72e536f81..0fcb6ba91 100644 --- a/build.rs +++ b/build.rs @@ -130,7 +130,7 @@ fn detect_cfgs(target: &mut Target) { Ok(target.has_symbol("localeconv_l")) }), ("FISH_USE_POSIX_SPAWN", &|target| { - Ok(target.has_header("spawn.h")) + Ok(false) // FIXME: expose to redox libc spawn }), ("HAVE_PIPE2", &|target| { Ok(target.has_symbol("pipe2")) diff --git a/src/exec.rs b/src/exec.rs index 40dea914e..42fba7ccb 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -33,7 +33,6 @@ use crate::nix::{getpid, isatty}; use crate::null_terminated_array::OwningNullTerminatedArray; use crate::parser::{Block, BlockId, BlockType, EvalRes, Parser}; -#[cfg(FISH_USE_POSIX_SPAWN)] use crate::proc::Pid; use crate::proc::{ hup_jobs, is_interactive_session, jobs_requiring_warning_on_exit, no_exec, @@ -390,7 +389,7 @@ fn safe_launch_process( ) -> ! { // This function never returns, so we take certain liberties with constness. - unsafe { libc::execve(actual_cmd.as_ptr(), argv.get(), envv.get()) }; + unsafe { libc::execve(actual_cmd.as_ptr(), argv.get().cast(), envv.get().cast()) }; let err = errno(); // The shebang wasn't introduced until UNIX Seventh Edition, so if @@ -413,7 +412,11 @@ fn safe_launch_process( // not what we would pass as argv0. argv2[1] = actual_cmd.as_ptr(); unsafe { - libc::execve(_PATH_BSHELL.load(Ordering::Relaxed), &argv2[0], envv.get()); + libc::execve( + _PATH_BSHELL.load(Ordering::Relaxed), + argv2.as_ptr().cast(), + envv.get().cast(), + ); } } } diff --git a/src/fork_exec/postfork.rs b/src/fork_exec/postfork.rs index 32182e42f..494fa82dd 100644 --- a/src/fork_exec/postfork.rs +++ b/src/fork_exec/postfork.rs @@ -339,7 +339,9 @@ pub(crate) fn safe_report_exec_error( "', which is not an executable command." ); } - } else if md.unwrap().mode() & u32::from(libc::S_IFMT) == u32::from(libc::S_IFDIR) { + } else if md.unwrap().mode() & u32::try_from(libc::S_IFMT).unwrap() + == u32::try_from(libc::S_IFDIR).unwrap() + { FLOG_SAFE!( exec, "Failed to execute process '", diff --git a/src/input_common.rs b/src/input_common.rs index 3f36b0209..e89709333 100644 --- a/src/input_common.rs +++ b/src/input_common.rs @@ -589,7 +589,9 @@ pub fn check_fd_readable(in_fd: RawFd, timeout: Duration) -> bool { // pselect expects timeouts in nanoseconds. const NSEC_PER_MSEC: u64 = 1000 * 1000; const NSEC_PER_SEC: u64 = NSEC_PER_MSEC * 1000; + #[cfg(not(target_os = "redox"))] let wait_nsec: u64 = (timeout.as_millis() as u64) * NSEC_PER_MSEC; + #[cfg(not(target_os = "redox"))] let timeout = libc::timespec { tv_sec: (wait_nsec / NSEC_PER_SEC).try_into().unwrap(), tv_nsec: (wait_nsec % NSEC_PER_SEC).try_into().unwrap(), @@ -605,6 +607,7 @@ pub fn check_fd_readable(in_fd: RawFd, timeout: Duration) -> bool { libc::FD_SET(in_fd, &mut fdset); } + #[cfg(not(target_os = "redox"))] let res = unsafe { libc::pselect( in_fd + 1, @@ -616,6 +619,31 @@ pub fn check_fd_readable(in_fd: RawFd, timeout: Duration) -> bool { ) }; + #[cfg(target_os = "redox")] + let res = unsafe { + //HACK: pselect does this atomically + let mut saved = MaybeUninit::uninit(); + let mut saved = { + libc::sigfillset(saved.as_mut_ptr()); + saved.assume_init() + }; + libc::sigprocmask(libc::SIG_SETMASK, &sigs, &mut saved); + let mut timeout = libc::timeval { + tv_sec: timeout.as_secs() as _, + tv_usec: timeout.subsec_micros() as _, + }; + let res = libc::select( + in_fd + 1, + &mut fdset, + ptr::null_mut(), + ptr::null_mut(), + &raw mut timeout, + ); + libc::sigprocmask(libc::SIG_SETMASK, &saved, ptr::null_mut()); + + res + }; + // Prevent signal starvation on WSL causing the `torn_escapes.py` test to fail if is_windows_subsystem_for_linux(WSL::V1) { // Merely querying the current thread's sigmask is sufficient to deliver a pending signal diff --git a/src/libc.c b/src/libc.c index 4eec100ab..c04ced9fe 100644 --- a/src/libc.c +++ b/src/libc.c @@ -4,7 +4,7 @@ #include #include #include // MB_CUR_MAX -#include // MNT_LOCAL +/* #include // MNT_LOCAL */ #include #include // ST_LOCAL #include // _CS_PATH, _PC_CASE_SENSITIVE diff --git a/src/path.rs b/src/path.rs index 7d7339d37..4b1791ece 100644 --- a/src/path.rs +++ b/src/path.rs @@ -738,7 +738,9 @@ fn remoteness_via_statfs( crate::libc::ST_LOCAL(), &narrow, ); - #[cfg(not(target_os = "netbsd"))] + #[cfg(target_os = "redox")] + let remoteness = DirRemoteness::unknown; + #[cfg(not(target_os = "redox"))] let remoteness = remoteness_via_statfs( libc::statfs, |stat: &libc::statfs| stat.f_flags,