From 8f50862be5601535e54917cbdd8bdd90917b86d0 Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Sun, 12 Jul 2026 15:18:01 +0300 Subject: [PATCH] Fix create_pipe: bypass redox_rt::sys::open two-step that consumes has_run_dup Use direct syscall::openat with ns_fd to get pipe READ end, then syscall::dup with 'write' to get WRITE end. This avoids the redox_rt::sys::open bug where step 2 (openat_into_posix on the pipe read end) consumes has_run_dup, leaving the subsequent dup() unable to get the write end. --- init/src/service.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/init/src/service.rs b/init/src/service.rs index dfa8b066c5..d4f15baeda 100644 --- a/init/src/service.rs +++ b/init/src/service.rs @@ -37,16 +37,25 @@ pub enum ServiceType { } fn create_pipe() -> io::Result<(File, OwnedFd)> { - let rd = libredox::Fd::open( + let ns_fd = libredox::call::getns() + .map_err(|e| io::Error::from_raw_os_error(e.errno()))?; + + let rd_fd = syscall::openat( + ns_fd, "/scheme/pipe", - libredox::flag::O_RDONLY | libredox::flag::O_CLOEXEC, + syscall::flag::O_RDONLY | syscall::flag::O_CLOEXEC, 0, ) - .map_err(|e| io::Error::from_raw_os_error(e.errno()))?; - let wr_raw = syscall::dup(rd.raw(), b"write") - .map_err(|e| io::Error::from_raw_os_error(e.errno))?; + .map_err(|e| io::Error::from_raw_os_error(e.errno))?; + + let wr_raw = syscall::dup(rd_fd, b"write") + .map_err(|e| { + let _ = syscall::close(rd_fd); + io::Error::from_raw_os_error(e.errno) + })?; + let wr = unsafe { OwnedFd::from_raw_fd(wr_raw as i32) }; - let rd = unsafe { File::from_raw_fd(rd.into_raw() as i32) }; + let rd = unsafe { File::from_raw_fd(rd_fd as i32) }; Ok((rd, wr)) }