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