about summary refs log tree commit diff
path: root/library/std/src/sys/pal/solid
diff options
context:
space:
mode:
authorThalia Archibald <thalia@archibald.dev>2025-04-21 20:56:43 -0700
committerThalia Archibald <thalia@archibald.dev>2025-04-21 20:56:43 -0700
commit90fe2805df75b9d46b985346f0dff2690c285330 (patch)
tree314e83705721dbd25abe01f5fa35885ca6c9b12a /library/std/src/sys/pal/solid
parentd6c1e454aa8af5e7e59fbf5c4e7d3128d2f99582 (diff)
Move `sys::pal::os::Env` into `sys::env`
Although `Env` (as `Vars`), `Args`, path functions, and OS constants are
publicly exposed via `std::env`, their implementations are each
self-contained. Keep them separate in `std::sys` and make a new module,
`sys::env`, for `Env`.
Diffstat (limited to 'library/std/src/sys/pal/solid')
-rw-r--r--library/std/src/sys/pal/solid/os.rs142
1 files changed, 2 insertions, 140 deletions
diff --git a/library/std/src/sys/pal/solid/os.rs b/library/std/src/sys/pal/solid/os.rs
index e3b2e0aa50f..8f5976b0592 100644
--- a/library/std/src/sys/pal/solid/os.rs
+++ b/library/std/src/sys/pal/solid/os.rs
@@ -1,14 +1,8 @@
-use core::slice::memchr;
-
 use super::{error, itron, unsupported};
 use crate::error::Error as StdError;
-use crate::ffi::{CStr, OsStr, OsString};
-use crate::os::raw::{c_char, c_int};
-use crate::os::solid::ffi::{OsStrExt, OsStringExt};
+use crate::ffi::{OsStr, OsString};
 use crate::path::{self, PathBuf};
-use crate::sync::{PoisonError, RwLock};
-use crate::sys::common::small_c_string::run_with_cstr;
-use crate::{fmt, io, vec};
+use crate::{fmt, io};
 
 // `solid` directly maps `errno`s to μITRON error codes.
 impl itron::error::ItronError {
@@ -75,138 +69,6 @@ pub fn current_exe() -> io::Result<PathBuf> {
     unsupported()
 }
 
-static ENV_LOCK: RwLock<()> = RwLock::new(());
-
-pub fn env_read_lock() -> impl Drop {
-    ENV_LOCK.read().unwrap_or_else(PoisonError::into_inner)
-}
-
-pub struct Env {
-    iter: vec::IntoIter<(OsString, OsString)>,
-}
-
-// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt.
-pub struct EnvStrDebug<'a> {
-    slice: &'a [(OsString, OsString)],
-}
-
-impl fmt::Debug for EnvStrDebug<'_> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let Self { slice } = self;
-        f.debug_list()
-            .entries(slice.iter().map(|(a, b)| (a.to_str().unwrap(), b.to_str().unwrap())))
-            .finish()
-    }
-}
-
-impl Env {
-    pub fn str_debug(&self) -> impl fmt::Debug + '_ {
-        let Self { iter } = self;
-        EnvStrDebug { slice: iter.as_slice() }
-    }
-}
-
-impl fmt::Debug for Env {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let Self { iter } = self;
-        f.debug_list().entries(iter.as_slice()).finish()
-    }
-}
-
-impl !Send for Env {}
-impl !Sync for Env {}
-
-impl Iterator for Env {
-    type Item = (OsString, OsString);
-    fn next(&mut self) -> Option<(OsString, OsString)> {
-        self.iter.next()
-    }
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        self.iter.size_hint()
-    }
-}
-
-/// Returns a vector of (variable, value) byte-vector pairs for all the
-/// environment variables of the current process.
-pub fn env() -> Env {
-    unsafe extern "C" {
-        static mut environ: *const *const c_char;
-    }
-
-    unsafe {
-        let _guard = env_read_lock();
-        let mut result = Vec::new();
-        if !environ.is_null() {
-            while !(*environ).is_null() {
-                if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
-                    result.push(key_value);
-                }
-                environ = environ.add(1);
-            }
-        }
-        return Env { iter: result.into_iter() };
-    }
-
-    fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
-        // Strategy (copied from glibc): Variable name and value are separated
-        // by an ASCII equals sign '='. Since a variable name must not be
-        // empty, allow variable names starting with an equals sign. Skip all
-        // malformed lines.
-        if input.is_empty() {
-            return None;
-        }
-        let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
-        pos.map(|p| {
-            (
-                OsStringExt::from_vec(input[..p].to_vec()),
-                OsStringExt::from_vec(input[p + 1..].to_vec()),
-            )
-        })
-    }
-}
-
-pub fn getenv(k: &OsStr) -> Option<OsString> {
-    // environment variables with a nul byte can't be set, so their value is
-    // always None as well
-    run_with_cstr(k.as_bytes(), &|k| {
-        let _guard = env_read_lock();
-        let v = unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char;
-
-        if v.is_null() {
-            Ok(None)
-        } else {
-            // SAFETY: `v` cannot be mutated while executing this line since we've a read lock
-            let bytes = unsafe { CStr::from_ptr(v) }.to_bytes().to_vec();
-
-            Ok(Some(OsStringExt::from_vec(bytes)))
-        }
-    })
-    .ok()
-    .flatten()
-}
-
-pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
-    run_with_cstr(k.as_bytes(), &|k| {
-        run_with_cstr(v.as_bytes(), &|v| {
-            let _guard = ENV_LOCK.write();
-            cvt_env(unsafe { libc::setenv(k.as_ptr(), v.as_ptr(), 1) }).map(drop)
-        })
-    })
-}
-
-pub unsafe fn unsetenv(n: &OsStr) -> io::Result<()> {
-    run_with_cstr(n.as_bytes(), &|nbuf| {
-        let _guard = ENV_LOCK.write();
-        cvt_env(unsafe { libc::unsetenv(nbuf.as_ptr()) }).map(drop)
-    })
-}
-
-/// In kmclib, `setenv` and `unsetenv` don't always set `errno`, so this
-/// function just returns a generic error.
-fn cvt_env(t: c_int) -> io::Result<c_int> {
-    if t == -1 { Err(io::const_error!(io::ErrorKind::Uncategorized, "failure")) } else { Ok(t) }
-}
-
 pub fn temp_dir() -> PathBuf {
     panic!("no standard temporary directory on this platform")
 }