From b54cadb88f8167ec4f5e10a1d09fb4db69d2ea76 Mon Sep 17 00:00:00 2001 From: Ron Williams Date: Tue, 2 Jan 2024 02:20:45 -0800 Subject: [PATCH] add libc scheme for /dev/tty etc. --- src/platform/redox/libcscheme.rs | 49 ++++++++++++++++++++++++++++++++ src/platform/redox/mod.rs | 5 ++++ 2 files changed, 54 insertions(+) create mode 100644 src/platform/redox/libcscheme.rs diff --git a/src/platform/redox/libcscheme.rs b/src/platform/redox/libcscheme.rs new file mode 100644 index 0000000000..11f78133b4 --- /dev/null +++ b/src/platform/redox/libcscheme.rs @@ -0,0 +1,49 @@ +use super::libredox; +use crate::{c_str::CStr, header::stdlib::getenv, platform::types::*}; +use core::{ptr, slice}; +use syscall::{Error, Result, EINVAL, EIO, ENOENT}; + +pub const LIBC_SCHEME: &'static str = "libc:"; + +const ENV_MAX_LEN: i32 = i32::MAX; + +macro_rules! env_str { + ($lit:expr) => { + #[allow(unused_unsafe)] + { + let val_bytes = unsafe { getenv(concat!($lit, "\0").as_ptr() as *const c_char) }; + if val_bytes != ptr::null_mut() { + if let Ok(val_str) = unsafe { CStr::from_ptr(val_bytes) }.to_str() { + Some(val_str) + } else { + None + } + } else { + None + } + } + }; +} + +pub fn open(path: &str, oflag: c_int, mode: mode_t) -> Result { + assert!(path.starts_with(LIBC_SCHEME)); + + let basename = match path.strip_prefix(LIBC_SCHEME) { + Some(path) => path.trim_start_matches('/').trim_end_matches('/'), + _ => return Err(Error::new(EIO)), + }; + + // Linux seems to allow you to read from or write to any of /dev/{stdin,stderr,stdout} + match basename { + "stderr" => syscall::dup(2, &[]), + "stdin" => syscall::dup(0, &[]), + "stdout" => syscall::dup(1, &[]), + "tty" => { + if let Some(tty) = env_str!("TTY") { + return libredox::open(tty, oflag, mode); + } + Err(Error::new(ENOENT)) + } + _ => Err(Error::new(ENOENT)), + } +} diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index cf113953eb..b4f0506e4e 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -42,6 +42,7 @@ mod clone; mod epoll; mod exec; mod extra; +mod libcscheme; mod libredox; pub(crate) mod path; mod ptrace; @@ -744,6 +745,10 @@ impl Pal for Sys { fn open(path: CStr, oflag: c_int, mode: mode_t) -> c_int { let path = path_from_c_str!(path); + if path.starts_with(libcscheme::LIBC_SCHEME) { + return e(libcscheme::open(path, oflag, mode)) as c_int; + } + e(libredox::open(path, oflag, mode)) as c_int }