2 use crate::error::Error as StdError;
3 use crate::ffi::{OsString, OsStr, CString, CStr};
6 use crate::marker::PhantomData;
7 use crate::os::wasi::prelude::*;
8 use crate::path::{self, PathBuf};
11 use crate::sys::memchr;
12 use crate::sys::{cvt, unsupported, Void};
15 #[cfg(not(target_feature = "atomics"))]
16 pub unsafe fn env_lock() -> impl Any {
17 // No need for a lock if we're single-threaded, but this function will need
18 // to get implemented for multi-threaded scenarios
21 pub fn errno() -> i32 {
24 static errno: libc::c_int;
27 unsafe { errno as i32 }
30 pub fn error_string(_errno: i32) -> String {
31 "operation failed".to_string()
34 pub fn getcwd() -> io::Result<PathBuf> {
38 pub fn chdir(_: &path::Path) -> io::Result<()> {
42 pub struct SplitPaths<'a>(&'a Void);
44 pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> {
48 impl<'a> Iterator for SplitPaths<'a> {
50 fn next(&mut self) -> Option<PathBuf> {
56 pub struct JoinPathsError;
58 pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
59 where I: Iterator<Item=T>, T: AsRef<OsStr>
64 impl fmt::Display for JoinPathsError {
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 "not supported on wasm yet".fmt(f)
70 impl StdError for JoinPathsError {
71 fn description(&self) -> &str {
72 "not supported on wasm yet"
76 pub fn current_exe() -> io::Result<PathBuf> {
81 iter: vec::IntoIter<(OsString, OsString)>,
82 _dont_send_or_sync_me: PhantomData<*mut ()>,
85 impl Iterator for Env {
86 type Item = (OsString, OsString);
87 fn next(&mut self) -> Option<(OsString, OsString)> { self.iter.next() }
88 fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
94 let _guard = env_lock();
95 let mut environ = libc::environ;
96 let mut result = Vec::new();
97 while environ != ptr::null_mut() && *environ != ptr::null_mut() {
98 if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
99 result.push(key_value);
101 environ = environ.offset(1);
104 iter: result.into_iter(),
105 _dont_send_or_sync_me: PhantomData,
109 // See src/libstd/sys/unix/os.rs, same as that
110 fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
111 if input.is_empty() {
114 let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
116 OsStringExt::from_vec(input[..p].to_vec()),
117 OsStringExt::from_vec(input[p+1..].to_vec()),
122 pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
123 let k = CString::new(k.as_bytes())?;
125 let _guard = env_lock();
126 let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
127 let ret = if s.is_null() {
130 Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
136 pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
137 let k = CString::new(k.as_bytes())?;
138 let v = CString::new(v.as_bytes())?;
141 let _guard = env_lock();
142 cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(|_| ())
146 pub fn unsetenv(n: &OsStr) -> io::Result<()> {
147 let nbuf = CString::new(n.as_bytes())?;
150 let _guard = env_lock();
151 cvt(libc::unsetenv(nbuf.as_ptr())).map(|_| ())
155 pub fn temp_dir() -> PathBuf {
156 panic!("no filesystem on wasm")
159 pub fn home_dir() -> Option<PathBuf> {
163 pub fn exit(code: i32) -> ! {
169 pub fn getpid() -> u32 {
170 panic!("unsupported");