]> git.proxmox.com Git - rustc.git/blob - src/libstd/sys/wasi/os.rs
New upstream version 1.42.0+dfsg1
[rustc.git] / src / libstd / sys / wasi / os.rs
1 use crate::any::Any;
2 use crate::error::Error as StdError;
3 use crate::ffi::{CStr, CString, OsStr, OsString};
4 use crate::fmt;
5 use crate::io;
6 use crate::marker::PhantomData;
7 use crate::os::wasi::prelude::*;
8 use crate::path::{self, PathBuf};
9 use crate::str;
10 use crate::sys::memchr;
11 use crate::sys::{unsupported, Void};
12 use crate::vec;
13
14 #[cfg(not(target_feature = "atomics"))]
15 pub unsafe fn env_lock() -> impl Any {
16 // No need for a lock if we're single-threaded, but this function will need
17 // to get implemented for multi-threaded scenarios
18 }
19
20 pub fn errno() -> i32 {
21 extern "C" {
22 #[thread_local]
23 static errno: libc::c_int;
24 }
25
26 unsafe { errno as i32 }
27 }
28
29 pub fn error_string(errno: i32) -> String {
30 let mut buf = [0 as libc::c_char; 1024];
31
32 let p = buf.as_mut_ptr();
33 unsafe {
34 if libc::strerror_r(errno as libc::c_int, p, buf.len()) < 0 {
35 panic!("strerror_r failure");
36 }
37 str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
38 }
39 }
40
41 pub fn getcwd() -> io::Result<PathBuf> {
42 unsupported()
43 }
44
45 pub fn chdir(_: &path::Path) -> io::Result<()> {
46 unsupported()
47 }
48
49 pub struct SplitPaths<'a>(&'a Void);
50
51 pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> {
52 panic!("unsupported")
53 }
54
55 impl<'a> Iterator for SplitPaths<'a> {
56 type Item = PathBuf;
57 fn next(&mut self) -> Option<PathBuf> {
58 match *self.0 {}
59 }
60 }
61
62 #[derive(Debug)]
63 pub struct JoinPathsError;
64
65 pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
66 where
67 I: Iterator<Item = T>,
68 T: AsRef<OsStr>,
69 {
70 Err(JoinPathsError)
71 }
72
73 impl fmt::Display for JoinPathsError {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 "not supported on wasm yet".fmt(f)
76 }
77 }
78
79 impl StdError for JoinPathsError {
80 #[allow(deprecated)]
81 fn description(&self) -> &str {
82 "not supported on wasm yet"
83 }
84 }
85
86 pub fn current_exe() -> io::Result<PathBuf> {
87 unsupported()
88 }
89 pub struct Env {
90 iter: vec::IntoIter<(OsString, OsString)>,
91 _dont_send_or_sync_me: PhantomData<*mut ()>,
92 }
93
94 impl Iterator for Env {
95 type Item = (OsString, OsString);
96 fn next(&mut self) -> Option<(OsString, OsString)> {
97 self.iter.next()
98 }
99 fn size_hint(&self) -> (usize, Option<usize>) {
100 self.iter.size_hint()
101 }
102 }
103
104 pub fn env() -> Env {
105 unsafe {
106 let _guard = env_lock();
107 let mut environ = libc::environ;
108 let mut result = Vec::new();
109 if !environ.is_null() {
110 while !(*environ).is_null() {
111 if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
112 result.push(key_value);
113 }
114 environ = environ.add(1);
115 }
116 }
117 return Env { iter: result.into_iter(), _dont_send_or_sync_me: PhantomData };
118 }
119
120 // See src/libstd/sys/unix/os.rs, same as that
121 fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
122 if input.is_empty() {
123 return None;
124 }
125 let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
126 pos.map(|p| {
127 (
128 OsStringExt::from_vec(input[..p].to_vec()),
129 OsStringExt::from_vec(input[p + 1..].to_vec()),
130 )
131 })
132 }
133 }
134
135 pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
136 let k = CString::new(k.as_bytes())?;
137 unsafe {
138 let _guard = env_lock();
139 let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
140 let ret = if s.is_null() {
141 None
142 } else {
143 Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
144 };
145 Ok(ret)
146 }
147 }
148
149 pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
150 let k = CString::new(k.as_bytes())?;
151 let v = CString::new(v.as_bytes())?;
152
153 unsafe {
154 let _guard = env_lock();
155 cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop)
156 }
157 }
158
159 pub fn unsetenv(n: &OsStr) -> io::Result<()> {
160 let nbuf = CString::new(n.as_bytes())?;
161
162 unsafe {
163 let _guard = env_lock();
164 cvt(libc::unsetenv(nbuf.as_ptr())).map(drop)
165 }
166 }
167
168 pub fn temp_dir() -> PathBuf {
169 panic!("no filesystem on wasm")
170 }
171
172 pub fn home_dir() -> Option<PathBuf> {
173 None
174 }
175
176 pub fn exit(code: i32) -> ! {
177 unsafe { libc::exit(code) }
178 }
179
180 pub fn getpid() -> u32 {
181 panic!("unsupported");
182 }
183
184 #[doc(hidden)]
185 pub trait IsMinusOne {
186 fn is_minus_one(&self) -> bool;
187 }
188
189 macro_rules! impl_is_minus_one {
190 ($($t:ident)*) => ($(impl IsMinusOne for $t {
191 fn is_minus_one(&self) -> bool {
192 *self == -1
193 }
194 })*)
195 }
196
197 impl_is_minus_one! { i8 i16 i32 i64 isize }
198
199 fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
200 if t.is_minus_one() { Err(io::Error::last_os_error()) } else { Ok(t) }
201 }