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