]>
Commit | Line | Data |
---|---|---|
85aaf69f SL |
1 | //! Inspection and manipulation of the process's environment. |
2 | //! | |
32a655c1 | 3 | //! This module contains functions to inspect various aspects such as |
c1a9b12d | 4 | //! environment variables, process arguments, the current directory, and various |
85aaf69f | 5 | //! other important directories. |
7cac9316 XL |
6 | //! |
7 | //! There are several functions and structs in this module that have a | |
8 | //! counterpart ending in `os`. Those ending in `os` will return an [`OsString`] | |
9 | //! and those without will be returning a [`String`]. | |
10 | //! | |
11 | //! [`OsString`]: ../../std/ffi/struct.OsString.html | |
12 | //! [`String`]: ../string/struct.String.html | |
85aaf69f | 13 | |
c34b1796 | 14 | #![stable(feature = "env", since = "1.0.0")] |
85aaf69f | 15 | |
532ac7d7 XL |
16 | use crate::error::Error; |
17 | use crate::ffi::{OsStr, OsString}; | |
18 | use crate::fmt; | |
19 | use crate::io; | |
20 | use crate::path::{Path, PathBuf}; | |
21 | use crate::sys; | |
22 | use crate::sys::os as os_imp; | |
85aaf69f | 23 | |
8bb4bdeb | 24 | /// Returns the current working directory as a [`PathBuf`]. |
85aaf69f SL |
25 | /// |
26 | /// # Errors | |
27 | /// | |
8bb4bdeb | 28 | /// Returns an [`Err`] if the current working directory value is invalid. |
85aaf69f SL |
29 | /// Possible cases: |
30 | /// | |
31 | /// * Current directory does not exist. | |
32 | /// * There are insufficient permissions to access the current directory. | |
85aaf69f | 33 | /// |
8bb4bdeb XL |
34 | /// [`PathBuf`]: ../../std/path/struct.PathBuf.html |
35 | /// [`Err`]: ../../std/result/enum.Result.html#method.err | |
36 | /// | |
c34b1796 | 37 | /// # Examples |
85aaf69f | 38 | /// |
c34b1796 | 39 | /// ``` |
85aaf69f SL |
40 | /// use std::env; |
41 | /// | |
94b46f34 XL |
42 | /// fn main() -> std::io::Result<()> { |
43 | /// let path = env::current_dir()?; | |
44 | /// println!("The current directory is {}", path.display()); | |
45 | /// Ok(()) | |
46 | /// } | |
85aaf69f | 47 | /// ``` |
c34b1796 AL |
48 | #[stable(feature = "env", since = "1.0.0")] |
49 | pub fn current_dir() -> io::Result<PathBuf> { | |
85aaf69f SL |
50 | os_imp::getcwd() |
51 | } | |
52 | ||
7cac9316 XL |
53 | /// Changes the current working directory to the specified path. |
54 | /// | |
55 | /// Returns an [`Err`] if the operation fails. | |
56 | /// | |
57 | /// [`Err`]: ../../std/result/enum.Result.html#method.err | |
85aaf69f | 58 | /// |
c34b1796 | 59 | /// # Examples |
85aaf69f | 60 | /// |
c34b1796 | 61 | /// ``` |
85aaf69f | 62 | /// use std::env; |
c34b1796 | 63 | /// use std::path::Path; |
85aaf69f SL |
64 | /// |
65 | /// let root = Path::new("/"); | |
66 | /// assert!(env::set_current_dir(&root).is_ok()); | |
67 | /// println!("Successfully changed working directory to {}!", root.display()); | |
68 | /// ``` | |
c34b1796 | 69 | #[stable(feature = "env", since = "1.0.0")] |
7cac9316 XL |
70 | pub fn set_current_dir<P: AsRef<Path>>(path: P) -> io::Result<()> { |
71 | os_imp::chdir(path.as_ref()) | |
85aaf69f SL |
72 | } |
73 | ||
85aaf69f SL |
74 | /// An iterator over a snapshot of the environment variables of this process. |
75 | /// | |
7cac9316 XL |
76 | /// This structure is created by the [`std::env::vars`] function. See its |
77 | /// documentation for more. | |
32a655c1 SL |
78 | /// |
79 | /// [`std::env::vars`]: fn.vars.html | |
c34b1796 | 80 | #[stable(feature = "env", since = "1.0.0")] |
60c5eb7d XL |
81 | pub struct Vars { |
82 | inner: VarsOs, | |
83 | } | |
85aaf69f SL |
84 | |
85 | /// An iterator over a snapshot of the environment variables of this process. | |
86 | /// | |
7cac9316 XL |
87 | /// This structure is created by the [`std::env::vars_os`] function. See |
88 | /// its documentation for more. | |
32a655c1 SL |
89 | /// |
90 | /// [`std::env::vars_os`]: fn.vars_os.html | |
c34b1796 | 91 | #[stable(feature = "env", since = "1.0.0")] |
60c5eb7d XL |
92 | pub struct VarsOs { |
93 | inner: os_imp::Env, | |
94 | } | |
85aaf69f SL |
95 | |
96 | /// Returns an iterator of (variable, value) pairs of strings, for all the | |
97 | /// environment variables of the current process. | |
98 | /// | |
99 | /// The returned iterator contains a snapshot of the process's environment | |
9e0c209e | 100 | /// variables at the time of this invocation. Modifications to environment |
85aaf69f SL |
101 | /// variables afterwards will not be reflected in the returned iterator. |
102 | /// | |
103 | /// # Panics | |
104 | /// | |
105 | /// While iterating, the returned iterator will panic if any key or value in the | |
106 | /// environment is not valid unicode. If this is not desired, consider using the | |
8bb4bdeb XL |
107 | /// [`env::vars_os`] function. |
108 | /// | |
109 | /// [`env::vars_os`]: fn.vars_os.html | |
85aaf69f | 110 | /// |
c34b1796 | 111 | /// # Examples |
85aaf69f | 112 | /// |
c34b1796 | 113 | /// ``` |
85aaf69f SL |
114 | /// use std::env; |
115 | /// | |
116 | /// // We will iterate through the references to the element returned by | |
117 | /// // env::vars(); | |
118 | /// for (key, value) in env::vars() { | |
119 | /// println!("{}: {}", key, value); | |
120 | /// } | |
121 | /// ``` | |
c34b1796 | 122 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f SL |
123 | pub fn vars() -> Vars { |
124 | Vars { inner: vars_os() } | |
125 | } | |
126 | ||
127 | /// Returns an iterator of (variable, value) pairs of OS strings, for all the | |
128 | /// environment variables of the current process. | |
129 | /// | |
130 | /// The returned iterator contains a snapshot of the process's environment | |
9e0c209e | 131 | /// variables at the time of this invocation. Modifications to environment |
85aaf69f SL |
132 | /// variables afterwards will not be reflected in the returned iterator. |
133 | /// | |
c34b1796 | 134 | /// # Examples |
85aaf69f | 135 | /// |
c34b1796 | 136 | /// ``` |
85aaf69f SL |
137 | /// use std::env; |
138 | /// | |
139 | /// // We will iterate through the references to the element returned by | |
140 | /// // env::vars_os(); | |
141 | /// for (key, value) in env::vars_os() { | |
142 | /// println!("{:?}: {:?}", key, value); | |
143 | /// } | |
144 | /// ``` | |
c34b1796 | 145 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f | 146 | pub fn vars_os() -> VarsOs { |
85aaf69f SL |
147 | VarsOs { inner: os_imp::env() } |
148 | } | |
149 | ||
c34b1796 | 150 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f SL |
151 | impl Iterator for Vars { |
152 | type Item = (String, String); | |
153 | fn next(&mut self) -> Option<(String, String)> { | |
60c5eb7d XL |
154 | self.inner.next().map(|(a, b)| (a.into_string().unwrap(), b.into_string().unwrap())) |
155 | } | |
156 | fn size_hint(&self) -> (usize, Option<usize>) { | |
157 | self.inner.size_hint() | |
85aaf69f | 158 | } |
85aaf69f SL |
159 | } |
160 | ||
8bb4bdeb | 161 | #[stable(feature = "std_debug", since = "1.16.0")] |
32a655c1 | 162 | impl fmt::Debug for Vars { |
532ac7d7 | 163 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
32a655c1 SL |
164 | f.pad("Vars { .. }") |
165 | } | |
166 | } | |
167 | ||
c34b1796 | 168 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f SL |
169 | impl Iterator for VarsOs { |
170 | type Item = (OsString, OsString); | |
60c5eb7d XL |
171 | fn next(&mut self) -> Option<(OsString, OsString)> { |
172 | self.inner.next() | |
173 | } | |
174 | fn size_hint(&self) -> (usize, Option<usize>) { | |
175 | self.inner.size_hint() | |
176 | } | |
85aaf69f SL |
177 | } |
178 | ||
8bb4bdeb | 179 | #[stable(feature = "std_debug", since = "1.16.0")] |
32a655c1 | 180 | impl fmt::Debug for VarsOs { |
532ac7d7 | 181 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
32a655c1 SL |
182 | f.pad("VarsOs { .. }") |
183 | } | |
184 | } | |
185 | ||
85aaf69f SL |
186 | /// Fetches the environment variable `key` from the current process. |
187 | /// | |
7cac9316 | 188 | /// # Errors |
8bb4bdeb | 189 | /// |
7cac9316 XL |
190 | /// * Environment variable is not present |
191 | /// * Environment variable is not valid unicode | |
85aaf69f | 192 | /// |
416331ca XL |
193 | /// # Panics |
194 | /// | |
195 | /// This function may panic if `key` is empty, contains an ASCII equals sign | |
196 | /// `'='` or the NUL character `'\0'`, or when the value contains the NUL | |
197 | /// character. | |
198 | /// | |
c34b1796 | 199 | /// # Examples |
85aaf69f | 200 | /// |
c34b1796 | 201 | /// ``` |
85aaf69f SL |
202 | /// use std::env; |
203 | /// | |
204 | /// let key = "HOME"; | |
205 | /// match env::var(key) { | |
206 | /// Ok(val) => println!("{}: {:?}", key, val), | |
207 | /// Err(e) => println!("couldn't interpret {}: {}", key, e), | |
208 | /// } | |
209 | /// ``` | |
c34b1796 | 210 | #[stable(feature = "env", since = "1.0.0")] |
d9579d0f | 211 | pub fn var<K: AsRef<OsStr>>(key: K) -> Result<String, VarError> { |
e9174d1e SL |
212 | _var(key.as_ref()) |
213 | } | |
214 | ||
215 | fn _var(key: &OsStr) -> Result<String, VarError> { | |
85aaf69f SL |
216 | match var_os(key) { |
217 | Some(s) => s.into_string().map_err(VarError::NotUnicode), | |
7cac9316 | 218 | None => Err(VarError::NotPresent), |
85aaf69f SL |
219 | } |
220 | } | |
221 | ||
222 | /// Fetches the environment variable `key` from the current process, returning | |
8bb4bdeb XL |
223 | /// [`None`] if the variable isn't set. |
224 | /// | |
225 | /// [`None`]: ../option/enum.Option.html#variant.None | |
85aaf69f | 226 | /// |
416331ca XL |
227 | /// # Panics |
228 | /// | |
229 | /// This function may panic if `key` is empty, contains an ASCII equals sign | |
230 | /// `'='` or the NUL character `'\0'`, or when the value contains the NUL | |
231 | /// character. | |
232 | /// | |
c34b1796 | 233 | /// # Examples |
85aaf69f | 234 | /// |
c34b1796 | 235 | /// ``` |
85aaf69f SL |
236 | /// use std::env; |
237 | /// | |
238 | /// let key = "HOME"; | |
239 | /// match env::var_os(key) { | |
240 | /// Some(val) => println!("{}: {:?}", key, val), | |
241 | /// None => println!("{} is not defined in the environment.", key) | |
242 | /// } | |
243 | /// ``` | |
c34b1796 | 244 | #[stable(feature = "env", since = "1.0.0")] |
d9579d0f | 245 | pub fn var_os<K: AsRef<OsStr>>(key: K) -> Option<OsString> { |
e9174d1e SL |
246 | _var_os(key.as_ref()) |
247 | } | |
248 | ||
249 | fn _var_os(key: &OsStr) -> Option<OsString> { | |
60c5eb7d XL |
250 | os_imp::getenv(key) |
251 | .unwrap_or_else(|e| panic!("failed to get environment variable `{:?}`: {}", key, e)) | |
85aaf69f SL |
252 | } |
253 | ||
7cac9316 XL |
254 | /// The error type for operations interacting with environment variables. |
255 | /// Possibly returned from the [`env::var`] function. | |
32a655c1 SL |
256 | /// |
257 | /// [`env::var`]: fn.var.html | |
85aaf69f | 258 | #[derive(Debug, PartialEq, Eq, Clone)] |
c34b1796 | 259 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f SL |
260 | pub enum VarError { |
261 | /// The specified environment variable was not present in the current | |
262 | /// process's environment. | |
c34b1796 | 263 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f SL |
264 | NotPresent, |
265 | ||
266 | /// The specified environment variable was found, but it did not contain | |
267 | /// valid unicode data. The found data is returned as a payload of this | |
268 | /// variant. | |
c34b1796 | 269 | #[stable(feature = "env", since = "1.0.0")] |
7453a54e | 270 | NotUnicode(#[stable(feature = "env", since = "1.0.0")] OsString), |
85aaf69f SL |
271 | } |
272 | ||
c34b1796 | 273 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f | 274 | impl fmt::Display for VarError { |
532ac7d7 | 275 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
85aaf69f SL |
276 | match *self { |
277 | VarError::NotPresent => write!(f, "environment variable not found"), | |
278 | VarError::NotUnicode(ref s) => { | |
279 | write!(f, "environment variable was not valid unicode: {:?}", s) | |
280 | } | |
281 | } | |
282 | } | |
283 | } | |
284 | ||
c34b1796 | 285 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f SL |
286 | impl Error for VarError { |
287 | fn description(&self) -> &str { | |
288 | match *self { | |
289 | VarError::NotPresent => "environment variable not found", | |
290 | VarError::NotUnicode(..) => "environment variable was not valid unicode", | |
291 | } | |
292 | } | |
293 | } | |
294 | ||
295 | /// Sets the environment variable `k` to the value `v` for the currently running | |
296 | /// process. | |
297 | /// | |
d9579d0f AL |
298 | /// Note that while concurrent access to environment variables is safe in Rust, |
299 | /// some platforms only expose inherently unsafe non-threadsafe APIs for | |
e1599b0c | 300 | /// inspecting the environment. As a result, extra care needs to be taken when |
d9579d0f AL |
301 | /// auditing calls to unsafe external FFI functions to ensure that any external |
302 | /// environment accesses are properly synchronized with accesses in Rust. | |
303 | /// | |
304 | /// Discussion of this unsafety on Unix may be found in: | |
305 | /// | |
306 | /// - [Austin Group Bugzilla](http://austingroupbugs.net/view.php?id=188) | |
307 | /// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2) | |
308 | /// | |
b039eaaf SL |
309 | /// # Panics |
310 | /// | |
311 | /// This function may panic if `key` is empty, contains an ASCII equals sign | |
312 | /// `'='` or the NUL character `'\0'`, or when the value contains the NUL | |
313 | /// character. | |
314 | /// | |
c34b1796 | 315 | /// # Examples |
85aaf69f | 316 | /// |
c34b1796 | 317 | /// ``` |
85aaf69f SL |
318 | /// use std::env; |
319 | /// | |
320 | /// let key = "KEY"; | |
321 | /// env::set_var(key, "VALUE"); | |
322 | /// assert_eq!(env::var(key), Ok("VALUE".to_string())); | |
323 | /// ``` | |
c34b1796 | 324 | #[stable(feature = "env", since = "1.0.0")] |
d9579d0f | 325 | pub fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(k: K, v: V) { |
e9174d1e SL |
326 | _set_var(k.as_ref(), v.as_ref()) |
327 | } | |
328 | ||
329 | fn _set_var(k: &OsStr, v: &OsStr) { | |
92a42be0 | 330 | os_imp::setenv(k, v).unwrap_or_else(|e| { |
60c5eb7d | 331 | panic!("failed to set environment variable `{:?}` to `{:?}`: {}", k, v, e) |
92a42be0 | 332 | }) |
85aaf69f SL |
333 | } |
334 | ||
9346a6ac | 335 | /// Removes an environment variable from the environment of the currently running process. |
c34b1796 | 336 | /// |
d9579d0f AL |
337 | /// Note that while concurrent access to environment variables is safe in Rust, |
338 | /// some platforms only expose inherently unsafe non-threadsafe APIs for | |
339 | /// inspecting the environment. As a result extra care needs to be taken when | |
340 | /// auditing calls to unsafe external FFI functions to ensure that any external | |
341 | /// environment accesses are properly synchronized with accesses in Rust. | |
342 | /// | |
343 | /// Discussion of this unsafety on Unix may be found in: | |
344 | /// | |
345 | /// - [Austin Group Bugzilla](http://austingroupbugs.net/view.php?id=188) | |
346 | /// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2) | |
347 | /// | |
b039eaaf SL |
348 | /// # Panics |
349 | /// | |
350 | /// This function may panic if `key` is empty, contains an ASCII equals sign | |
351 | /// `'='` or the NUL character `'\0'`, or when the value contains the NUL | |
352 | /// character. | |
353 | /// | |
c34b1796 AL |
354 | /// # Examples |
355 | /// | |
356 | /// ``` | |
357 | /// use std::env; | |
358 | /// | |
359 | /// let key = "KEY"; | |
360 | /// env::set_var(key, "VALUE"); | |
361 | /// assert_eq!(env::var(key), Ok("VALUE".to_string())); | |
362 | /// | |
363 | /// env::remove_var(key); | |
364 | /// assert!(env::var(key).is_err()); | |
365 | /// ``` | |
366 | #[stable(feature = "env", since = "1.0.0")] | |
d9579d0f | 367 | pub fn remove_var<K: AsRef<OsStr>>(k: K) { |
e9174d1e SL |
368 | _remove_var(k.as_ref()) |
369 | } | |
370 | ||
371 | fn _remove_var(k: &OsStr) { | |
60c5eb7d XL |
372 | os_imp::unsetenv(k) |
373 | .unwrap_or_else(|e| panic!("failed to remove environment variable `{:?}`: {}", k, e)) | |
85aaf69f SL |
374 | } |
375 | ||
7cac9316 XL |
376 | /// An iterator that splits an environment variable into paths according to |
377 | /// platform-specific conventions. | |
378 | /// | |
48663c56 XL |
379 | /// The iterator element type is [`PathBuf`]. |
380 | /// | |
041b39d2 | 381 | /// This structure is created by the [`std::env::split_paths`] function. See its |
7cac9316 | 382 | /// documentation for more. |
85aaf69f | 383 | /// |
48663c56 | 384 | /// [`PathBuf`]: ../../std/path/struct.PathBuf.html |
7cac9316 | 385 | /// [`std::env::split_paths`]: fn.split_paths.html |
c34b1796 | 386 | #[stable(feature = "env", since = "1.0.0")] |
60c5eb7d XL |
387 | pub struct SplitPaths<'a> { |
388 | inner: os_imp::SplitPaths<'a>, | |
389 | } | |
85aaf69f SL |
390 | |
391 | /// Parses input according to platform conventions for the `PATH` | |
392 | /// environment variable. | |
393 | /// | |
48663c56 XL |
394 | /// Returns an iterator over the paths contained in `unparsed`. The iterator |
395 | /// element type is [`PathBuf`]. | |
85aaf69f | 396 | /// |
c34b1796 | 397 | /// # Examples |
85aaf69f | 398 | /// |
c34b1796 | 399 | /// ``` |
85aaf69f SL |
400 | /// use std::env; |
401 | /// | |
402 | /// let key = "PATH"; | |
403 | /// match env::var_os(key) { | |
404 | /// Some(paths) => { | |
405 | /// for path in env::split_paths(&paths) { | |
406 | /// println!("'{}'", path.display()); | |
407 | /// } | |
408 | /// } | |
409 | /// None => println!("{} is not defined in the environment.", key) | |
410 | /// } | |
411 | /// ``` | |
48663c56 XL |
412 | /// |
413 | /// [`PathBuf`]: ../../std/path/struct.PathBuf.html | |
c34b1796 | 414 | #[stable(feature = "env", since = "1.0.0")] |
532ac7d7 | 415 | pub fn split_paths<T: AsRef<OsStr> + ?Sized>(unparsed: &T) -> SplitPaths<'_> { |
c34b1796 | 416 | SplitPaths { inner: os_imp::split_paths(unparsed.as_ref()) } |
85aaf69f SL |
417 | } |
418 | ||
c34b1796 | 419 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f | 420 | impl<'a> Iterator for SplitPaths<'a> { |
c34b1796 | 421 | type Item = PathBuf; |
60c5eb7d XL |
422 | fn next(&mut self) -> Option<PathBuf> { |
423 | self.inner.next() | |
424 | } | |
425 | fn size_hint(&self) -> (usize, Option<usize>) { | |
426 | self.inner.size_hint() | |
427 | } | |
85aaf69f SL |
428 | } |
429 | ||
8bb4bdeb | 430 | #[stable(feature = "std_debug", since = "1.16.0")] |
9fa01778 | 431 | impl fmt::Debug for SplitPaths<'_> { |
532ac7d7 | 432 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
32a655c1 SL |
433 | f.pad("SplitPaths { .. }") |
434 | } | |
435 | } | |
436 | ||
7cac9316 XL |
437 | /// The error type for operations on the `PATH` variable. Possibly returned from |
438 | /// the [`env::join_paths`] function. | |
439 | /// | |
440 | /// [`env::join_paths`]: fn.join_paths.html | |
85aaf69f | 441 | #[derive(Debug)] |
c34b1796 | 442 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f | 443 | pub struct JoinPathsError { |
60c5eb7d | 444 | inner: os_imp::JoinPathsError, |
85aaf69f SL |
445 | } |
446 | ||
8bb4bdeb | 447 | /// Joins a collection of [`Path`]s appropriately for the `PATH` |
85aaf69f SL |
448 | /// environment variable. |
449 | /// | |
7cac9316 | 450 | /// # Errors |
85aaf69f | 451 | /// |
8bb4bdeb XL |
452 | /// Returns an [`Err`][err] (containing an error message) if one of the input |
453 | /// [`Path`]s contains an invalid character for constructing the `PATH` | |
85aaf69f SL |
454 | /// variable (a double quote on Windows or a colon on Unix). |
455 | /// | |
8bb4bdeb XL |
456 | /// [`Path`]: ../../std/path/struct.Path.html |
457 | /// [`OsString`]: ../../std/ffi/struct.OsString.html | |
458 | /// [err]: ../../std/result/enum.Result.html#variant.Err | |
459 | /// | |
c34b1796 | 460 | /// # Examples |
85aaf69f | 461 | /// |
041b39d2 XL |
462 | /// Joining paths on a Unix-like platform: |
463 | /// | |
464 | /// ``` | |
041b39d2 XL |
465 | /// use std::env; |
466 | /// use std::ffi::OsString; | |
467 | /// use std::path::Path; | |
468 | /// | |
94b46f34 XL |
469 | /// fn main() -> Result<(), env::JoinPathsError> { |
470 | /// # if cfg!(unix) { | |
471 | /// let paths = [Path::new("/bin"), Path::new("/usr/bin")]; | |
472 | /// let path_os_string = env::join_paths(paths.iter())?; | |
473 | /// assert_eq!(path_os_string, OsString::from("/bin:/usr/bin")); | |
041b39d2 | 474 | /// # } |
94b46f34 XL |
475 | /// Ok(()) |
476 | /// } | |
041b39d2 XL |
477 | /// ``` |
478 | /// | |
479 | /// Joining a path containing a colon on a Unix-like platform results in an error: | |
480 | /// | |
481 | /// ``` | |
482 | /// # if cfg!(unix) { | |
483 | /// use std::env; | |
484 | /// use std::path::Path; | |
485 | /// | |
486 | /// let paths = [Path::new("/bin"), Path::new("/usr/bi:n")]; | |
487 | /// assert!(env::join_paths(paths.iter()).is_err()); | |
488 | /// # } | |
489 | /// ``` | |
490 | /// | |
dc9dc135 | 491 | /// Using `env::join_paths` with [`env::split_paths`] to append an item to the `PATH` environment |
041b39d2 XL |
492 | /// variable: |
493 | /// | |
c34b1796 | 494 | /// ``` |
85aaf69f | 495 | /// use std::env; |
c34b1796 | 496 | /// use std::path::PathBuf; |
85aaf69f | 497 | /// |
94b46f34 XL |
498 | /// fn main() -> Result<(), env::JoinPathsError> { |
499 | /// if let Some(path) = env::var_os("PATH") { | |
500 | /// let mut paths = env::split_paths(&path).collect::<Vec<_>>(); | |
501 | /// paths.push(PathBuf::from("/home/xyz/bin")); | |
502 | /// let new_path = env::join_paths(paths)?; | |
503 | /// env::set_var("PATH", &new_path); | |
504 | /// } | |
505 | /// | |
506 | /// Ok(()) | |
85aaf69f SL |
507 | /// } |
508 | /// ``` | |
dc9dc135 XL |
509 | /// |
510 | /// [`env::split_paths`]: fn.split_paths.html | |
c34b1796 | 511 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f | 512 | pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError> |
60c5eb7d XL |
513 | where |
514 | I: IntoIterator<Item = T>, | |
515 | T: AsRef<OsStr>, | |
85aaf69f | 516 | { |
60c5eb7d | 517 | os_imp::join_paths(paths.into_iter()).map_err(|e| JoinPathsError { inner: e }) |
85aaf69f SL |
518 | } |
519 | ||
c34b1796 | 520 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f | 521 | impl fmt::Display for JoinPathsError { |
532ac7d7 | 522 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
85aaf69f SL |
523 | self.inner.fmt(f) |
524 | } | |
525 | } | |
526 | ||
c34b1796 | 527 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f | 528 | impl Error for JoinPathsError { |
60c5eb7d XL |
529 | fn description(&self) -> &str { |
530 | self.inner.description() | |
531 | } | |
85aaf69f SL |
532 | } |
533 | ||
54a0048b | 534 | /// Returns the path of the current user's home directory if known. |
85aaf69f SL |
535 | /// |
536 | /// # Unix | |
537 | /// | |
8faf50e0 XL |
538 | /// - Returns the value of the 'HOME' environment variable if it is set |
539 | /// (including to an empty string). | |
540 | /// - Otherwise, it tries to determine the home directory by invoking the `getpwuid_r` function | |
541 | /// using the UID of the current user. An empty home directory field returned from the | |
542 | /// `getpwuid_r` function is considered to be a valid value. | |
543 | /// - Returns `None` if the current user has no entry in the /etc/passwd file. | |
85aaf69f SL |
544 | /// |
545 | /// # Windows | |
546 | /// | |
8faf50e0 XL |
547 | /// - Returns the value of the 'HOME' environment variable if it is set |
548 | /// (including to an empty string). | |
549 | /// - Otherwise, returns the value of the 'USERPROFILE' environment variable if it is set | |
550 | /// (including to an empty string). | |
551 | /// - If both do not exist, [`GetUserProfileDirectory`][msdn] is used to return the path. | |
b039eaaf SL |
552 | /// |
553 | /// [msdn]: https://msdn.microsoft.com/en-us/library/windows/desktop/bb762280(v=vs.85).aspx | |
85aaf69f | 554 | /// |
c34b1796 | 555 | /// # Examples |
85aaf69f | 556 | /// |
c34b1796 | 557 | /// ``` |
85aaf69f SL |
558 | /// use std::env; |
559 | /// | |
560 | /// match env::home_dir() { | |
8faf50e0 | 561 | /// Some(path) => println!("Your home directory, probably: {}", path.display()), |
7453a54e | 562 | /// None => println!("Impossible to get your home dir!"), |
85aaf69f SL |
563 | /// } |
564 | /// ``` | |
60c5eb7d XL |
565 | #[rustc_deprecated( |
566 | since = "1.29.0", | |
8faf50e0 | 567 | reason = "This function's behavior is unexpected and probably not what you want. \ |
60c5eb7d XL |
568 | Consider using the home_dir function from https://crates.io/crates/dirs instead." |
569 | )] | |
c34b1796 AL |
570 | #[stable(feature = "env", since = "1.0.0")] |
571 | pub fn home_dir() -> Option<PathBuf> { | |
85aaf69f SL |
572 | os_imp::home_dir() |
573 | } | |
574 | ||
54a0048b | 575 | /// Returns the path of a temporary directory. |
85aaf69f | 576 | /// |
7cac9316 XL |
577 | /// # Unix |
578 | /// | |
579 | /// Returns the value of the `TMPDIR` environment variable if it is | |
a7813a04 XL |
580 | /// set, otherwise for non-Android it returns `/tmp`. If Android, since there |
581 | /// is no global temporary folder (it is usually allocated per-app), it returns | |
582 | /// `/data/local/tmp`. | |
583 | /// | |
7cac9316 XL |
584 | /// # Windows |
585 | /// | |
586 | /// Returns the value of, in order, the `TMP`, `TEMP`, | |
a7813a04 XL |
587 | /// `USERPROFILE` environment variable if any are set and not the empty |
588 | /// string. Otherwise, `temp_dir` returns the path of the Windows directory. | |
589 | /// This behavior is identical to that of [`GetTempPath`][msdn], which this | |
590 | /// function uses internally. | |
b039eaaf SL |
591 | /// |
592 | /// [msdn]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992(v=vs.85).aspx | |
c34b1796 | 593 | /// |
0531ce1d | 594 | /// ```no_run |
c34b1796 AL |
595 | /// use std::env; |
596 | /// use std::fs::File; | |
597 | /// | |
0531ce1d XL |
598 | /// fn main() -> std::io::Result<()> { |
599 | /// let mut dir = env::temp_dir(); | |
600 | /// dir.push("foo.txt"); | |
c34b1796 | 601 | /// |
0531ce1d XL |
602 | /// let f = File::create(dir)?; |
603 | /// Ok(()) | |
604 | /// } | |
c34b1796 AL |
605 | /// ``` |
606 | #[stable(feature = "env", since = "1.0.0")] | |
607 | pub fn temp_dir() -> PathBuf { | |
85aaf69f SL |
608 | os_imp::temp_dir() |
609 | } | |
610 | ||
54a0048b | 611 | /// Returns the full filesystem path of the current running executable. |
85aaf69f | 612 | /// |
2c00a5a8 XL |
613 | /// # Platform-specific behavior |
614 | /// | |
615 | /// If the executable was invoked through a symbolic link, some platforms will | |
616 | /// return the path of the symbolic link and other platforms will return the | |
617 | /// path of the symbolic link’s target. | |
85aaf69f SL |
618 | /// |
619 | /// # Errors | |
620 | /// | |
54a0048b | 621 | /// Acquiring the path of the current executable is a platform-specific operation |
85aaf69f | 622 | /// that can fail for a good number of reasons. Some errors can include, but not |
7453a54e | 623 | /// be limited to, filesystem operations failing or general syscall failures. |
85aaf69f | 624 | /// |
5bcae85e SL |
625 | /// # Security |
626 | /// | |
627 | /// The output of this function should not be used in anything that might have | |
628 | /// security implications. For example: | |
629 | /// | |
630 | /// ``` | |
631 | /// fn main() { | |
632 | /// println!("{:?}", std::env::current_exe()); | |
633 | /// } | |
634 | /// ``` | |
635 | /// | |
636 | /// On Linux systems, if this is compiled as `foo`: | |
637 | /// | |
638 | /// ```bash | |
639 | /// $ rustc foo.rs | |
640 | /// $ ./foo | |
641 | /// Ok("/home/alex/foo") | |
642 | /// ``` | |
643 | /// | |
2c00a5a8 | 644 | /// And you make a hard link of the program: |
5bcae85e SL |
645 | /// |
646 | /// ```bash | |
647 | /// $ ln foo bar | |
648 | /// ``` | |
649 | /// | |
2c00a5a8 XL |
650 | /// When you run it, you won’t get the path of the original executable, you’ll |
651 | /// get the path of the hard link: | |
5bcae85e SL |
652 | /// |
653 | /// ```bash | |
654 | /// $ ./bar | |
655 | /// Ok("/home/alex/bar") | |
656 | /// ``` | |
657 | /// | |
658 | /// This sort of behavior has been known to [lead to privilege escalation] when | |
2c00a5a8 | 659 | /// used incorrectly. |
5bcae85e | 660 | /// |
2c00a5a8 | 661 | /// [lead to privilege escalation]: https://securityvulns.com/Wdocument183.html |
5bcae85e | 662 | /// |
85aaf69f SL |
663 | /// # Examples |
664 | /// | |
c34b1796 | 665 | /// ``` |
85aaf69f SL |
666 | /// use std::env; |
667 | /// | |
668 | /// match env::current_exe() { | |
669 | /// Ok(exe_path) => println!("Path of this executable is: {}", | |
2c00a5a8 | 670 | /// exe_path.display()), |
85aaf69f SL |
671 | /// Err(e) => println!("failed to get current exe path: {}", e), |
672 | /// }; | |
673 | /// ``` | |
c34b1796 AL |
674 | #[stable(feature = "env", since = "1.0.0")] |
675 | pub fn current_exe() -> io::Result<PathBuf> { | |
85aaf69f SL |
676 | os_imp::current_exe() |
677 | } | |
678 | ||
041b39d2 XL |
679 | /// An iterator over the arguments of a process, yielding a [`String`] value for |
680 | /// each argument. | |
85aaf69f | 681 | /// |
041b39d2 XL |
682 | /// This struct is created by the [`std::env::args`] function. See its |
683 | /// documentation for more. | |
476ff2be | 684 | /// |
8bb4bdeb | 685 | /// The first element is traditionally the path of the executable, but it can be |
041b39d2 XL |
686 | /// set to arbitrary text, and may not even exist. This means this property |
687 | /// should not be relied upon for security purposes. | |
8bb4bdeb | 688 | /// |
476ff2be SL |
689 | /// [`String`]: ../string/struct.String.html |
690 | /// [`std::env::args`]: ./fn.args.html | |
c34b1796 | 691 | #[stable(feature = "env", since = "1.0.0")] |
60c5eb7d XL |
692 | pub struct Args { |
693 | inner: ArgsOs, | |
694 | } | |
85aaf69f | 695 | |
476ff2be | 696 | /// An iterator over the arguments of a process, yielding an [`OsString`] value |
85aaf69f SL |
697 | /// for each argument. |
698 | /// | |
041b39d2 XL |
699 | /// This struct is created by the [`std::env::args_os`] function. See its |
700 | /// documentation for more. | |
476ff2be | 701 | /// |
8bb4bdeb | 702 | /// The first element is traditionally the path of the executable, but it can be |
041b39d2 XL |
703 | /// set to arbitrary text, and may not even exist. This means this property |
704 | /// should not be relied upon for security purposes. | |
8bb4bdeb | 705 | /// |
476ff2be SL |
706 | /// [`OsString`]: ../ffi/struct.OsString.html |
707 | /// [`std::env::args_os`]: ./fn.args_os.html | |
c34b1796 | 708 | #[stable(feature = "env", since = "1.0.0")] |
60c5eb7d XL |
709 | pub struct ArgsOs { |
710 | inner: sys::args::Args, | |
711 | } | |
85aaf69f SL |
712 | |
713 | /// Returns the arguments which this program was started with (normally passed | |
714 | /// via the command line). | |
715 | /// | |
54a0048b | 716 | /// The first element is traditionally the path of the executable, but it can be |
7453a54e | 717 | /// set to arbitrary text, and may not even exist. This means this property should |
85aaf69f SL |
718 | /// not be relied upon for security purposes. |
719 | /// | |
abe05a73 XL |
720 | /// On Unix systems shell usually expands unquoted arguments with glob patterns |
721 | /// (such as `*` and `?`). On Windows this is not done, and such arguments are | |
722 | /// passed as-is. | |
723 | /// | |
60c5eb7d XL |
724 | /// On glibc Linux, arguments are retrieved by placing a function in .init_array. |
725 | /// glibc passes argc, argv, and envp to functions in .init_array, as a non-standard extension. | |
726 | /// This allows `std::env::args` to work even in a `cdylib` or `staticlib`, as it does on macOS | |
727 | /// and Windows. | |
728 | /// | |
85aaf69f SL |
729 | /// # Panics |
730 | /// | |
731 | /// The returned iterator will panic during iteration if any argument to the | |
7453a54e | 732 | /// process is not valid unicode. If this is not desired, |
476ff2be | 733 | /// use the [`args_os`] function instead. |
85aaf69f | 734 | /// |
c34b1796 | 735 | /// # Examples |
85aaf69f | 736 | /// |
c34b1796 | 737 | /// ``` |
85aaf69f SL |
738 | /// use std::env; |
739 | /// | |
740 | /// // Prints each argument on a separate line | |
741 | /// for argument in env::args() { | |
742 | /// println!("{}", argument); | |
743 | /// } | |
744 | /// ``` | |
476ff2be SL |
745 | /// |
746 | /// [`args_os`]: ./fn.args_os.html | |
c34b1796 | 747 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f SL |
748 | pub fn args() -> Args { |
749 | Args { inner: args_os() } | |
750 | } | |
751 | ||
752 | /// Returns the arguments which this program was started with (normally passed | |
753 | /// via the command line). | |
754 | /// | |
54a0048b | 755 | /// The first element is traditionally the path of the executable, but it can be |
85aaf69f SL |
756 | /// set to arbitrary text, and it may not even exist, so this property should |
757 | /// not be relied upon for security purposes. | |
758 | /// | |
60c5eb7d XL |
759 | /// On glibc Linux, arguments are retrieved by placing a function in .init_array. |
760 | /// glibc passes argc, argv, and envp to functions in .init_array, as a non-standard extension. | |
761 | /// This allows `std::env::args` to work even in a `cdylib` or `staticlib`, as it does on macOS | |
762 | /// and Windows. | |
763 | /// | |
c34b1796 | 764 | /// # Examples |
85aaf69f | 765 | /// |
c34b1796 | 766 | /// ``` |
85aaf69f SL |
767 | /// use std::env; |
768 | /// | |
769 | /// // Prints each argument on a separate line | |
770 | /// for argument in env::args_os() { | |
771 | /// println!("{:?}", argument); | |
772 | /// } | |
773 | /// ``` | |
c34b1796 | 774 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f | 775 | pub fn args_os() -> ArgsOs { |
c30ab7b3 | 776 | ArgsOs { inner: sys::args::args() } |
85aaf69f SL |
777 | } |
778 | ||
83c7162d | 779 | #[stable(feature = "env_unimpl_send_sync", since = "1.26.0")] |
0531ce1d XL |
780 | impl !Send for Args {} |
781 | ||
83c7162d | 782 | #[stable(feature = "env_unimpl_send_sync", since = "1.26.0")] |
0531ce1d XL |
783 | impl !Sync for Args {} |
784 | ||
c34b1796 | 785 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f SL |
786 | impl Iterator for Args { |
787 | type Item = String; | |
788 | fn next(&mut self) -> Option<String> { | |
789 | self.inner.next().map(|s| s.into_string().unwrap()) | |
790 | } | |
60c5eb7d XL |
791 | fn size_hint(&self) -> (usize, Option<usize>) { |
792 | self.inner.size_hint() | |
793 | } | |
85aaf69f SL |
794 | } |
795 | ||
c34b1796 | 796 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f | 797 | impl ExactSizeIterator for Args { |
60c5eb7d XL |
798 | fn len(&self) -> usize { |
799 | self.inner.len() | |
800 | } | |
801 | fn is_empty(&self) -> bool { | |
802 | self.inner.is_empty() | |
803 | } | |
85aaf69f SL |
804 | } |
805 | ||
7cac9316 | 806 | #[stable(feature = "env_iterators", since = "1.12.0")] |
5bcae85e SL |
807 | impl DoubleEndedIterator for Args { |
808 | fn next_back(&mut self) -> Option<String> { | |
809 | self.inner.next_back().map(|s| s.into_string().unwrap()) | |
810 | } | |
811 | } | |
812 | ||
8bb4bdeb | 813 | #[stable(feature = "std_debug", since = "1.16.0")] |
32a655c1 | 814 | impl fmt::Debug for Args { |
532ac7d7 | 815 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
60c5eb7d | 816 | f.debug_struct("Args").field("inner", &self.inner.inner.inner_debug()).finish() |
32a655c1 SL |
817 | } |
818 | } | |
819 | ||
83c7162d | 820 | #[stable(feature = "env_unimpl_send_sync", since = "1.26.0")] |
0531ce1d XL |
821 | impl !Send for ArgsOs {} |
822 | ||
83c7162d | 823 | #[stable(feature = "env_unimpl_send_sync", since = "1.26.0")] |
0531ce1d XL |
824 | impl !Sync for ArgsOs {} |
825 | ||
c34b1796 | 826 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f SL |
827 | impl Iterator for ArgsOs { |
828 | type Item = OsString; | |
60c5eb7d XL |
829 | fn next(&mut self) -> Option<OsString> { |
830 | self.inner.next() | |
831 | } | |
832 | fn size_hint(&self) -> (usize, Option<usize>) { | |
833 | self.inner.size_hint() | |
834 | } | |
85aaf69f SL |
835 | } |
836 | ||
c34b1796 | 837 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f | 838 | impl ExactSizeIterator for ArgsOs { |
60c5eb7d XL |
839 | fn len(&self) -> usize { |
840 | self.inner.len() | |
841 | } | |
842 | fn is_empty(&self) -> bool { | |
843 | self.inner.is_empty() | |
844 | } | |
85aaf69f SL |
845 | } |
846 | ||
7cac9316 | 847 | #[stable(feature = "env_iterators", since = "1.12.0")] |
5bcae85e | 848 | impl DoubleEndedIterator for ArgsOs { |
60c5eb7d XL |
849 | fn next_back(&mut self) -> Option<OsString> { |
850 | self.inner.next_back() | |
851 | } | |
5bcae85e | 852 | } |
32a655c1 | 853 | |
8bb4bdeb | 854 | #[stable(feature = "std_debug", since = "1.16.0")] |
32a655c1 | 855 | impl fmt::Debug for ArgsOs { |
532ac7d7 | 856 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
60c5eb7d | 857 | f.debug_struct("ArgsOs").field("inner", &self.inner.inner_debug()).finish() |
32a655c1 SL |
858 | } |
859 | } | |
860 | ||
85aaf69f | 861 | /// Constants associated with the current target |
c34b1796 | 862 | #[stable(feature = "env", since = "1.0.0")] |
85aaf69f | 863 | pub mod consts { |
532ac7d7 | 864 | use crate::sys::env::os; |
c30ab7b3 | 865 | |
7453a54e | 866 | /// A string describing the architecture of the CPU that is currently |
c34b1796 | 867 | /// in use. |
62682a34 SL |
868 | /// |
869 | /// Some possible values: | |
870 | /// | |
871 | /// - x86 | |
872 | /// - x86_64 | |
873 | /// - arm | |
874 | /// - aarch64 | |
875 | /// - mips | |
9e0c209e | 876 | /// - mips64 |
62682a34 | 877 | /// - powerpc |
9cc50fc6 | 878 | /// - powerpc64 |
9e0c209e | 879 | /// - s390x |
32a655c1 | 880 | /// - sparc64 |
c34b1796 | 881 | #[stable(feature = "env", since = "1.0.0")] |
0731742a | 882 | pub const ARCH: &str = super::arch::ARCH; |
85aaf69f | 883 | |
54a0048b | 884 | /// The family of the operating system. Example value is `unix`. |
62682a34 SL |
885 | /// |
886 | /// Some possible values: | |
887 | /// | |
888 | /// - unix | |
889 | /// - windows | |
c34b1796 | 890 | #[stable(feature = "env", since = "1.0.0")] |
0731742a | 891 | pub const FAMILY: &str = os::FAMILY; |
85aaf69f | 892 | |
54a0048b SL |
893 | /// A string describing the specific operating system in use. |
894 | /// Example value is `linux`. | |
62682a34 SL |
895 | /// |
896 | /// Some possible values: | |
897 | /// | |
898 | /// - linux | |
899 | /// - macos | |
900 | /// - ios | |
901 | /// - freebsd | |
902 | /// - dragonfly | |
c1a9b12d | 903 | /// - netbsd |
62682a34 | 904 | /// - openbsd |
7453a54e | 905 | /// - solaris |
62682a34 SL |
906 | /// - android |
907 | /// - windows | |
c34b1796 | 908 | #[stable(feature = "env", since = "1.0.0")] |
0731742a | 909 | pub const OS: &str = os::OS; |
85aaf69f SL |
910 | |
911 | /// Specifies the filename prefix used for shared libraries on this | |
54a0048b | 912 | /// platform. Example value is `lib`. |
62682a34 SL |
913 | /// |
914 | /// Some possible values: | |
915 | /// | |
916 | /// - lib | |
917 | /// - `""` (an empty string) | |
c34b1796 | 918 | #[stable(feature = "env", since = "1.0.0")] |
0731742a | 919 | pub const DLL_PREFIX: &str = os::DLL_PREFIX; |
85aaf69f SL |
920 | |
921 | /// Specifies the filename suffix used for shared libraries on this | |
54a0048b | 922 | /// platform. Example value is `.so`. |
62682a34 SL |
923 | /// |
924 | /// Some possible values: | |
925 | /// | |
926 | /// - .so | |
927 | /// - .dylib | |
928 | /// - .dll | |
c34b1796 | 929 | #[stable(feature = "env", since = "1.0.0")] |
0731742a | 930 | pub const DLL_SUFFIX: &str = os::DLL_SUFFIX; |
85aaf69f SL |
931 | |
932 | /// Specifies the file extension used for shared libraries on this | |
54a0048b | 933 | /// platform that goes after the dot. Example value is `so`. |
62682a34 SL |
934 | /// |
935 | /// Some possible values: | |
936 | /// | |
92a42be0 SL |
937 | /// - so |
938 | /// - dylib | |
939 | /// - dll | |
c34b1796 | 940 | #[stable(feature = "env", since = "1.0.0")] |
0731742a | 941 | pub const DLL_EXTENSION: &str = os::DLL_EXTENSION; |
85aaf69f SL |
942 | |
943 | /// Specifies the filename suffix used for executable binaries on this | |
54a0048b | 944 | /// platform. Example value is `.exe`. |
62682a34 SL |
945 | /// |
946 | /// Some possible values: | |
947 | /// | |
92a42be0 SL |
948 | /// - .exe |
949 | /// - .nexe | |
950 | /// - .pexe | |
62682a34 | 951 | /// - `""` (an empty string) |
c34b1796 | 952 | #[stable(feature = "env", since = "1.0.0")] |
0731742a | 953 | pub const EXE_SUFFIX: &str = os::EXE_SUFFIX; |
85aaf69f SL |
954 | |
955 | /// Specifies the file extension, if any, used for executable binaries | |
54a0048b | 956 | /// on this platform. Example value is `exe`. |
62682a34 SL |
957 | /// |
958 | /// Some possible values: | |
959 | /// | |
960 | /// - exe | |
961 | /// - `""` (an empty string) | |
c34b1796 | 962 | #[stable(feature = "env", since = "1.0.0")] |
0731742a | 963 | pub const EXE_EXTENSION: &str = os::EXE_EXTENSION; |
9e0c209e SL |
964 | } |
965 | ||
85aaf69f | 966 | #[cfg(target_arch = "x86")] |
c34b1796 | 967 | mod arch { |
0731742a | 968 | pub const ARCH: &str = "x86"; |
85aaf69f SL |
969 | } |
970 | ||
971 | #[cfg(target_arch = "x86_64")] | |
c34b1796 | 972 | mod arch { |
0731742a | 973 | pub const ARCH: &str = "x86_64"; |
85aaf69f SL |
974 | } |
975 | ||
976 | #[cfg(target_arch = "arm")] | |
c34b1796 | 977 | mod arch { |
0731742a | 978 | pub const ARCH: &str = "arm"; |
85aaf69f SL |
979 | } |
980 | ||
981 | #[cfg(target_arch = "aarch64")] | |
c34b1796 | 982 | mod arch { |
0731742a | 983 | pub const ARCH: &str = "aarch64"; |
85aaf69f SL |
984 | } |
985 | ||
986 | #[cfg(target_arch = "mips")] | |
c34b1796 | 987 | mod arch { |
0731742a | 988 | pub const ARCH: &str = "mips"; |
85aaf69f SL |
989 | } |
990 | ||
9e0c209e SL |
991 | #[cfg(target_arch = "mips64")] |
992 | mod arch { | |
0731742a | 993 | pub const ARCH: &str = "mips64"; |
9e0c209e SL |
994 | } |
995 | ||
85aaf69f | 996 | #[cfg(target_arch = "powerpc")] |
c34b1796 | 997 | mod arch { |
0731742a | 998 | pub const ARCH: &str = "powerpc"; |
85aaf69f SL |
999 | } |
1000 | ||
9cc50fc6 SL |
1001 | #[cfg(target_arch = "powerpc64")] |
1002 | mod arch { | |
0731742a | 1003 | pub const ARCH: &str = "powerpc64"; |
9cc50fc6 SL |
1004 | } |
1005 | ||
9e0c209e SL |
1006 | #[cfg(target_arch = "s390x")] |
1007 | mod arch { | |
0731742a | 1008 | pub const ARCH: &str = "s390x"; |
9e0c209e SL |
1009 | } |
1010 | ||
32a655c1 SL |
1011 | #[cfg(target_arch = "sparc64")] |
1012 | mod arch { | |
0731742a | 1013 | pub const ARCH: &str = "sparc64"; |
32a655c1 SL |
1014 | } |
1015 | ||
7453a54e | 1016 | #[cfg(target_arch = "le32")] |
9cc50fc6 | 1017 | mod arch { |
0731742a | 1018 | pub const ARCH: &str = "le32"; |
9cc50fc6 SL |
1019 | } |
1020 | ||
7453a54e | 1021 | #[cfg(target_arch = "asmjs")] |
92a42be0 | 1022 | mod arch { |
0731742a | 1023 | pub const ARCH: &str = "asmjs"; |
92a42be0 SL |
1024 | } |
1025 | ||
c30ab7b3 SL |
1026 | #[cfg(target_arch = "wasm32")] |
1027 | mod arch { | |
0731742a | 1028 | pub const ARCH: &str = "wasm32"; |
c30ab7b3 SL |
1029 | } |
1030 | ||
416331ca XL |
1031 | #[cfg(target_arch = "hexagon")] |
1032 | mod arch { | |
1033 | pub const ARCH: &'static str = "hexagon"; | |
1034 | } | |
1035 | ||
85aaf69f SL |
1036 | #[cfg(test)] |
1037 | mod tests { | |
85aaf69f | 1038 | use super::*; |
c34b1796 | 1039 | |
532ac7d7 | 1040 | use crate::path::Path; |
85aaf69f | 1041 | |
85aaf69f | 1042 | #[test] |
532ac7d7 | 1043 | #[cfg_attr(any(target_os = "emscripten", target_env = "sgx"), ignore)] |
85aaf69f SL |
1044 | fn test_self_exe_path() { |
1045 | let path = current_exe(); | |
1046 | assert!(path.is_ok()); | |
1047 | let path = path.unwrap(); | |
1048 | ||
1049 | // Hard to test this function | |
1050 | assert!(path.is_absolute()); | |
1051 | } | |
1052 | ||
85aaf69f SL |
1053 | #[test] |
1054 | fn test() { | |
1055 | assert!((!Path::new("test-path").is_absolute())); | |
1056 | ||
532ac7d7 | 1057 | #[cfg(not(target_env = "sgx"))] |
85aaf69f SL |
1058 | current_dir().unwrap(); |
1059 | } | |
1060 | ||
1061 | #[test] | |
1062 | #[cfg(windows)] | |
1063 | fn split_paths_windows() { | |
532ac7d7 | 1064 | use crate::path::PathBuf; |
2c00a5a8 | 1065 | |
85aaf69f | 1066 | fn check_parse(unparsed: &str, parsed: &[&str]) -> bool { |
60c5eb7d XL |
1067 | split_paths(unparsed).collect::<Vec<_>>() |
1068 | == parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>() | |
85aaf69f SL |
1069 | } |
1070 | ||
1071 | assert!(check_parse("", &mut [""])); | |
1072 | assert!(check_parse(r#""""#, &mut [""])); | |
1073 | assert!(check_parse(";;", &mut ["", "", ""])); | |
1074 | assert!(check_parse(r"c:\", &mut [r"c:\"])); | |
1075 | assert!(check_parse(r"c:\;", &mut [r"c:\", ""])); | |
60c5eb7d | 1076 | assert!(check_parse(r"c:\;c:\Program Files\", &mut [r"c:\", r"c:\Program Files\"])); |
85aaf69f | 1077 | assert!(check_parse(r#"c:\;c:\"foo"\"#, &mut [r"c:\", r"c:\foo\"])); |
60c5eb7d XL |
1078 | assert!(check_parse( |
1079 | r#"c:\;c:\"foo;bar"\;c:\baz"#, | |
1080 | &mut [r"c:\", r"c:\foo;bar\", r"c:\baz"] | |
1081 | )); | |
85aaf69f SL |
1082 | } |
1083 | ||
1084 | #[test] | |
1085 | #[cfg(unix)] | |
1086 | fn split_paths_unix() { | |
532ac7d7 | 1087 | use crate::path::PathBuf; |
2c00a5a8 | 1088 | |
85aaf69f | 1089 | fn check_parse(unparsed: &str, parsed: &[&str]) -> bool { |
60c5eb7d XL |
1090 | split_paths(unparsed).collect::<Vec<_>>() |
1091 | == parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>() | |
85aaf69f SL |
1092 | } |
1093 | ||
1094 | assert!(check_parse("", &mut [""])); | |
1095 | assert!(check_parse("::", &mut ["", "", ""])); | |
1096 | assert!(check_parse("/", &mut ["/"])); | |
1097 | assert!(check_parse("/:", &mut ["/", ""])); | |
1098 | assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"])); | |
1099 | } | |
1100 | ||
1101 | #[test] | |
1102 | #[cfg(unix)] | |
1103 | fn join_paths_unix() { | |
532ac7d7 | 1104 | use crate::ffi::OsStr; |
2c00a5a8 | 1105 | |
85aaf69f | 1106 | fn test_eq(input: &[&str], output: &str) -> bool { |
60c5eb7d | 1107 | &*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output) |
85aaf69f SL |
1108 | } |
1109 | ||
1110 | assert!(test_eq(&[], "")); | |
60c5eb7d XL |
1111 | assert!(test_eq(&["/bin", "/usr/bin", "/usr/local/bin"], "/bin:/usr/bin:/usr/local/bin")); |
1112 | assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""], ":/bin:::/usr/bin:")); | |
85aaf69f SL |
1113 | assert!(join_paths(["/te:st"].iter().cloned()).is_err()); |
1114 | } | |
1115 | ||
1116 | #[test] | |
1117 | #[cfg(windows)] | |
1118 | fn join_paths_windows() { | |
532ac7d7 | 1119 | use crate::ffi::OsStr; |
2c00a5a8 | 1120 | |
85aaf69f | 1121 | fn test_eq(input: &[&str], output: &str) -> bool { |
60c5eb7d | 1122 | &*join_paths(input.iter().cloned()).unwrap() == OsStr::new(output) |
85aaf69f SL |
1123 | } |
1124 | ||
1125 | assert!(test_eq(&[], "")); | |
60c5eb7d XL |
1126 | assert!(test_eq(&[r"c:\windows", r"c:\"], r"c:\windows;c:\")); |
1127 | assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""], r";c:\windows;;;c:\;")); | |
1128 | assert!(test_eq(&[r"c:\te;st", r"c:\"], r#""c:\te;st";c:\"#)); | |
85aaf69f SL |
1129 | assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err()); |
1130 | } | |
041b39d2 XL |
1131 | |
1132 | #[test] | |
1133 | fn args_debug() { | |
1134 | assert_eq!( | |
1135 | format!("Args {{ inner: {:?} }}", args().collect::<Vec<_>>()), | |
60c5eb7d XL |
1136 | format!("{:?}", args()) |
1137 | ); | |
041b39d2 XL |
1138 | assert_eq!( |
1139 | format!("ArgsOs {{ inner: {:?} }}", args_os().collect::<Vec<_>>()), | |
60c5eb7d XL |
1140 | format!("{:?}", args_os()) |
1141 | ); | |
85aaf69f | 1142 | } |
041b39d2 | 1143 | } |