std/
env.rs

1//! Inspection and manipulation of the process's environment.
2//!
3//! This module contains functions to inspect various aspects such as
4//! environment variables, process arguments, the current directory, and various
5//! other important directories.
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 return a [`String`].
10
11#![stable(feature = "env", since = "1.0.0")]
12
13use crate::error::Error;
14use crate::ffi::{OsStr, OsString};
15use crate::path::{Path, PathBuf};
16use crate::sys::os as os_imp;
17use crate::{fmt, io, sys};
18
19/// Returns the current working directory as a [`PathBuf`].
20///
21/// # Platform-specific behavior
22///
23/// This function [currently] corresponds to the `getcwd` function on Unix
24/// and the `GetCurrentDirectoryW` function on Windows.
25///
26/// [currently]: crate::io#platform-specific-behavior
27///
28/// # Errors
29///
30/// Returns an [`Err`] if the current working directory value is invalid.
31/// Possible cases:
32///
33/// * Current directory does not exist.
34/// * There are insufficient permissions to access the current directory.
35///
36/// # Examples
37///
38/// ```
39/// use std::env;
40///
41/// fn main() -> std::io::Result<()> {
42///     let path = env::current_dir()?;
43///     println!("The current directory is {}", path.display());
44///     Ok(())
45/// }
46/// ```
47#[doc(alias = "pwd")]
48#[doc(alias = "getcwd")]
49#[doc(alias = "GetCurrentDirectory")]
50#[stable(feature = "env", since = "1.0.0")]
51pub fn current_dir() -> io::Result<PathBuf> {
52    os_imp::getcwd()
53}
54
55/// Changes the current working directory to the specified path.
56///
57/// # Platform-specific behavior
58///
59/// This function [currently] corresponds to the `chdir` function on Unix
60/// and the `SetCurrentDirectoryW` function on Windows.
61///
62/// Returns an [`Err`] if the operation fails.
63///
64/// [currently]: crate::io#platform-specific-behavior
65///
66/// # Examples
67///
68/// ```
69/// use std::env;
70/// use std::path::Path;
71///
72/// let root = Path::new("/");
73/// assert!(env::set_current_dir(&root).is_ok());
74/// println!("Successfully changed working directory to {}!", root.display());
75/// ```
76#[doc(alias = "chdir", alias = "SetCurrentDirectory", alias = "SetCurrentDirectoryW")]
77#[stable(feature = "env", since = "1.0.0")]
78pub fn set_current_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
79    os_imp::chdir(path.as_ref())
80}
81
82/// An iterator over a snapshot of the environment variables of this process.
83///
84/// This structure is created by [`env::vars()`]. See its documentation for more.
85///
86/// [`env::vars()`]: vars
87#[stable(feature = "env", since = "1.0.0")]
88pub struct Vars {
89    inner: VarsOs,
90}
91
92/// An iterator over a snapshot of the environment variables of this process.
93///
94/// This structure is created by [`env::vars_os()`]. See its documentation for more.
95///
96/// [`env::vars_os()`]: vars_os
97#[stable(feature = "env", since = "1.0.0")]
98pub struct VarsOs {
99    inner: os_imp::Env,
100}
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
106/// variables at the time of this invocation. Modifications to environment
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
113/// [`env::vars_os()`].
114///
115/// # Examples
116///
117/// ```
118/// // Print all environment variables.
119/// for (key, value) in std::env::vars() {
120///     println!("{key}: {value}");
121/// }
122/// ```
123///
124/// [`env::vars_os()`]: vars_os
125#[must_use]
126#[stable(feature = "env", since = "1.0.0")]
127pub fn vars() -> Vars {
128    Vars { inner: vars_os() }
129}
130
131/// Returns an iterator of (variable, value) pairs of OS strings, for all the
132/// environment variables of the current process.
133///
134/// The returned iterator contains a snapshot of the process's environment
135/// variables at the time of this invocation. Modifications to environment
136/// variables afterwards will not be reflected in the returned iterator.
137///
138/// Note that the returned iterator will not check if the environment variables
139/// are valid Unicode. If you want to panic on invalid UTF-8,
140/// use the [`vars`] function instead.
141///
142/// # Examples
143///
144/// ```
145/// // Print all environment variables.
146/// for (key, value) in std::env::vars_os() {
147///     println!("{key:?}: {value:?}");
148/// }
149/// ```
150#[must_use]
151#[stable(feature = "env", since = "1.0.0")]
152pub fn vars_os() -> VarsOs {
153    VarsOs { inner: os_imp::env() }
154}
155
156#[stable(feature = "env", since = "1.0.0")]
157impl Iterator for Vars {
158    type Item = (String, String);
159    fn next(&mut self) -> Option<(String, String)> {
160        self.inner.next().map(|(a, b)| (a.into_string().unwrap(), b.into_string().unwrap()))
161    }
162    fn size_hint(&self) -> (usize, Option<usize>) {
163        self.inner.size_hint()
164    }
165}
166
167#[stable(feature = "std_debug", since = "1.16.0")]
168impl fmt::Debug for Vars {
169    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170        let Self { inner: VarsOs { inner } } = self;
171        f.debug_struct("Vars").field("inner", &inner.str_debug()).finish()
172    }
173}
174
175#[stable(feature = "env", since = "1.0.0")]
176impl Iterator for VarsOs {
177    type Item = (OsString, OsString);
178    fn next(&mut self) -> Option<(OsString, OsString)> {
179        self.inner.next()
180    }
181    fn size_hint(&self) -> (usize, Option<usize>) {
182        self.inner.size_hint()
183    }
184}
185
186#[stable(feature = "std_debug", since = "1.16.0")]
187impl fmt::Debug for VarsOs {
188    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
189        let Self { inner } = self;
190        f.debug_struct("VarsOs").field("inner", inner).finish()
191    }
192}
193
194/// Fetches the environment variable `key` from the current process.
195///
196/// # Errors
197///
198/// Returns [`VarError::NotPresent`] if:
199/// - The variable is not set.
200/// - The variable's name contains an equal sign or NUL (`'='` or `'\0'`).
201///
202/// Returns [`VarError::NotUnicode`] if the variable's value is not valid
203/// Unicode. If this is not desired, consider using [`var_os`].
204///
205/// Use [`env!`] or [`option_env!`] instead if you want to check environment
206/// variables at compile time.
207///
208/// # Examples
209///
210/// ```
211/// use std::env;
212///
213/// let key = "HOME";
214/// match env::var(key) {
215///     Ok(val) => println!("{key}: {val:?}"),
216///     Err(e) => println!("couldn't interpret {key}: {e}"),
217/// }
218/// ```
219#[stable(feature = "env", since = "1.0.0")]
220pub fn var<K: AsRef<OsStr>>(key: K) -> Result<String, VarError> {
221    _var(key.as_ref())
222}
223
224fn _var(key: &OsStr) -> Result<String, VarError> {
225    match var_os(key) {
226        Some(s) => s.into_string().map_err(VarError::NotUnicode),
227        None => Err(VarError::NotPresent),
228    }
229}
230
231/// Fetches the environment variable `key` from the current process, returning
232/// [`None`] if the variable isn't set or if there is another error.
233///
234/// It may return `None` if the environment variable's name contains
235/// the equal sign character (`=`) or the NUL character.
236///
237/// Note that this function will not check if the environment variable
238/// is valid Unicode. If you want to have an error on invalid UTF-8,
239/// use the [`var`] function instead.
240///
241/// # Examples
242///
243/// ```
244/// use std::env;
245///
246/// let key = "HOME";
247/// match env::var_os(key) {
248///     Some(val) => println!("{key}: {val:?}"),
249///     None => println!("{key} is not defined in the environment.")
250/// }
251/// ```
252///
253/// If expecting a delimited variable (such as `PATH`), [`split_paths`]
254/// can be used to separate items.
255#[must_use]
256#[stable(feature = "env", since = "1.0.0")]
257pub fn var_os<K: AsRef<OsStr>>(key: K) -> Option<OsString> {
258    _var_os(key.as_ref())
259}
260
261fn _var_os(key: &OsStr) -> Option<OsString> {
262    os_imp::getenv(key)
263}
264
265/// The error type for operations interacting with environment variables.
266/// Possibly returned from [`env::var()`].
267///
268/// [`env::var()`]: var
269#[derive(Debug, PartialEq, Eq, Clone)]
270#[stable(feature = "env", since = "1.0.0")]
271pub enum VarError {
272    /// The specified environment variable was not present in the current
273    /// process's environment.
274    #[stable(feature = "env", since = "1.0.0")]
275    NotPresent,
276
277    /// The specified environment variable was found, but it did not contain
278    /// valid unicode data. The found data is returned as a payload of this
279    /// variant.
280    #[stable(feature = "env", since = "1.0.0")]
281    NotUnicode(#[stable(feature = "env", since = "1.0.0")] OsString),
282}
283
284#[stable(feature = "env", since = "1.0.0")]
285impl fmt::Display for VarError {
286    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
287        match *self {
288            VarError::NotPresent => write!(f, "environment variable not found"),
289            VarError::NotUnicode(ref s) => {
290                write!(f, "environment variable was not valid unicode: {:?}", s)
291            }
292        }
293    }
294}
295
296#[stable(feature = "env", since = "1.0.0")]
297impl Error for VarError {
298    #[allow(deprecated)]
299    fn description(&self) -> &str {
300        match *self {
301            VarError::NotPresent => "environment variable not found",
302            VarError::NotUnicode(..) => "environment variable was not valid unicode",
303        }
304    }
305}
306
307/// Sets the environment variable `key` to the value `value` for the currently running
308/// process.
309///
310/// # Safety
311///
312/// This function is safe to call in a single-threaded program.
313///
314/// This function is also always safe to call on Windows, in single-threaded
315/// and multi-threaded programs.
316///
317/// In multi-threaded programs on other operating systems, the only safe option is
318/// to not use `set_var` or `remove_var` at all.
319///
320/// The exact requirement is: you
321/// must ensure that there are no other threads concurrently writing or
322/// *reading*(!) the environment through functions or global variables other
323/// than the ones in this module. The problem is that these operating systems
324/// do not provide a thread-safe way to read the environment, and most C
325/// libraries, including libc itself, do not advertise which functions read
326/// from the environment. Even functions from the Rust standard library may
327/// read the environment without going through this module, e.g. for DNS
328/// lookups from [`std::net::ToSocketAddrs`]. No stable guarantee is made about
329/// which functions may read from the environment in future versions of a
330/// library. All this makes it not practically possible for you to guarantee
331/// that no other thread will read the environment, so the only safe option is
332/// to not use `set_var` or `remove_var` in multi-threaded programs at all.
333///
334/// Discussion of this unsafety on Unix may be found in:
335///
336///  - [Austin Group Bugzilla (for POSIX)](https://austingroupbugs.net/view.php?id=188)
337///  - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2)
338///
339/// To pass an environment variable to a child process, you can instead use [`Command::env`].
340///
341/// [`std::net::ToSocketAddrs`]: crate::net::ToSocketAddrs
342/// [`Command::env`]: crate::process::Command::env
343///
344/// # Panics
345///
346/// This function may panic if `key` is empty, contains an ASCII equals sign `'='`
347/// or the NUL character `'\0'`, or when `value` contains the NUL character.
348///
349/// # Examples
350///
351/// ```
352/// use std::env;
353///
354/// let key = "KEY";
355/// unsafe {
356///     env::set_var(key, "VALUE");
357/// }
358/// assert_eq!(env::var(key), Ok("VALUE".to_string()));
359/// ```
360#[rustc_deprecated_safe_2024(
361    audit_that = "the environment access only happens in single-threaded code"
362)]
363#[stable(feature = "env", since = "1.0.0")]
364pub unsafe fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) {
365    let (key, value) = (key.as_ref(), value.as_ref());
366    unsafe { os_imp::setenv(key, value) }.unwrap_or_else(|e| {
367        panic!("failed to set environment variable `{key:?}` to `{value:?}`: {e}")
368    })
369}
370
371/// Removes an environment variable from the environment of the currently running process.
372///
373/// # Safety
374///
375/// This function is safe to call in a single-threaded program.
376///
377/// This function is also always safe to call on Windows, in single-threaded
378/// and multi-threaded programs.
379///
380/// In multi-threaded programs on other operating systems, the only safe option is
381/// to not use `set_var` or `remove_var` at all.
382///
383/// The exact requirement is: you
384/// must ensure that there are no other threads concurrently writing or
385/// *reading*(!) the environment through functions or global variables other
386/// than the ones in this module. The problem is that these operating systems
387/// do not provide a thread-safe way to read the environment, and most C
388/// libraries, including libc itself, do not advertise which functions read
389/// from the environment. Even functions from the Rust standard library may
390/// read the environment without going through this module, e.g. for DNS
391/// lookups from [`std::net::ToSocketAddrs`]. No stable guarantee is made about
392/// which functions may read from the environment in future versions of a
393/// library. All this makes it not practically possible for you to guarantee
394/// that no other thread will read the environment, so the only safe option is
395/// to not use `set_var` or `remove_var` in multi-threaded programs at all.
396///
397/// Discussion of this unsafety on Unix may be found in:
398///
399///  - [Austin Group Bugzilla](https://austingroupbugs.net/view.php?id=188)
400///  - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2)
401///
402/// To prevent a child process from inheriting an environment variable, you can
403/// instead use [`Command::env_remove`] or [`Command::env_clear`].
404///
405/// [`std::net::ToSocketAddrs`]: crate::net::ToSocketAddrs
406/// [`Command::env_remove`]: crate::process::Command::env_remove
407/// [`Command::env_clear`]: crate::process::Command::env_clear
408///
409/// # Panics
410///
411/// This function may panic if `key` is empty, contains an ASCII equals sign
412/// `'='` or the NUL character `'\0'`, or when the value contains the NUL
413/// character.
414///
415/// # Examples
416///
417/// ```no_run
418/// use std::env;
419///
420/// let key = "KEY";
421/// unsafe {
422///     env::set_var(key, "VALUE");
423/// }
424/// assert_eq!(env::var(key), Ok("VALUE".to_string()));
425///
426/// unsafe {
427///     env::remove_var(key);
428/// }
429/// assert!(env::var(key).is_err());
430/// ```
431#[rustc_deprecated_safe_2024(
432    audit_that = "the environment access only happens in single-threaded code"
433)]
434#[stable(feature = "env", since = "1.0.0")]
435pub unsafe fn remove_var<K: AsRef<OsStr>>(key: K) {
436    let key = key.as_ref();
437    unsafe { os_imp::unsetenv(key) }
438        .unwrap_or_else(|e| panic!("failed to remove environment variable `{key:?}`: {e}"))
439}
440
441/// An iterator that splits an environment variable into paths according to
442/// platform-specific conventions.
443///
444/// The iterator element type is [`PathBuf`].
445///
446/// This structure is created by [`env::split_paths()`]. See its
447/// documentation for more.
448///
449/// [`env::split_paths()`]: split_paths
450#[must_use = "iterators are lazy and do nothing unless consumed"]
451#[stable(feature = "env", since = "1.0.0")]
452pub struct SplitPaths<'a> {
453    inner: os_imp::SplitPaths<'a>,
454}
455
456/// Parses input according to platform conventions for the `PATH`
457/// environment variable.
458///
459/// Returns an iterator over the paths contained in `unparsed`. The iterator
460/// element type is [`PathBuf`].
461///
462/// On most Unix platforms, the separator is `:` and on Windows it is `;`. This
463/// also performs unquoting on Windows.
464///
465/// [`join_paths`] can be used to recombine elements.
466///
467/// # Panics
468///
469/// This will panic on systems where there is no delimited `PATH` variable,
470/// such as UEFI.
471///
472/// # Examples
473///
474/// ```
475/// use std::env;
476///
477/// let key = "PATH";
478/// match env::var_os(key) {
479///     Some(paths) => {
480///         for path in env::split_paths(&paths) {
481///             println!("'{}'", path.display());
482///         }
483///     }
484///     None => println!("{key} is not defined in the environment.")
485/// }
486/// ```
487#[stable(feature = "env", since = "1.0.0")]
488pub fn split_paths<T: AsRef<OsStr> + ?Sized>(unparsed: &T) -> SplitPaths<'_> {
489    SplitPaths { inner: os_imp::split_paths(unparsed.as_ref()) }
490}
491
492#[stable(feature = "env", since = "1.0.0")]
493impl<'a> Iterator for SplitPaths<'a> {
494    type Item = PathBuf;
495    fn next(&mut self) -> Option<PathBuf> {
496        self.inner.next()
497    }
498    fn size_hint(&self) -> (usize, Option<usize>) {
499        self.inner.size_hint()
500    }
501}
502
503#[stable(feature = "std_debug", since = "1.16.0")]
504impl fmt::Debug for SplitPaths<'_> {
505    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
506        f.debug_struct("SplitPaths").finish_non_exhaustive()
507    }
508}
509
510/// The error type for operations on the `PATH` variable. Possibly returned from
511/// [`env::join_paths()`].
512///
513/// [`env::join_paths()`]: join_paths
514#[derive(Debug)]
515#[stable(feature = "env", since = "1.0.0")]
516pub struct JoinPathsError {
517    inner: os_imp::JoinPathsError,
518}
519
520/// Joins a collection of [`Path`]s appropriately for the `PATH`
521/// environment variable.
522///
523/// # Errors
524///
525/// Returns an [`Err`] (containing an error message) if one of the input
526/// [`Path`]s contains an invalid character for constructing the `PATH`
527/// variable (a double quote on Windows or a colon on Unix), or if the system
528/// does not have a `PATH`-like variable (e.g. UEFI or WASI).
529///
530/// # Examples
531///
532/// Joining paths on a Unix-like platform:
533///
534/// ```
535/// use std::env;
536/// use std::ffi::OsString;
537/// use std::path::Path;
538///
539/// fn main() -> Result<(), env::JoinPathsError> {
540/// # if cfg!(unix) {
541///     let paths = [Path::new("/bin"), Path::new("/usr/bin")];
542///     let path_os_string = env::join_paths(paths.iter())?;
543///     assert_eq!(path_os_string, OsString::from("/bin:/usr/bin"));
544/// # }
545///     Ok(())
546/// }
547/// ```
548///
549/// Joining a path containing a colon on a Unix-like platform results in an
550/// error:
551///
552/// ```
553/// # if cfg!(unix) {
554/// use std::env;
555/// use std::path::Path;
556///
557/// let paths = [Path::new("/bin"), Path::new("/usr/bi:n")];
558/// assert!(env::join_paths(paths.iter()).is_err());
559/// # }
560/// ```
561///
562/// Using `env::join_paths()` with [`env::split_paths()`] to append an item to
563/// the `PATH` environment variable:
564///
565/// ```
566/// use std::env;
567/// use std::path::PathBuf;
568///
569/// fn main() -> Result<(), env::JoinPathsError> {
570///     if let Some(path) = env::var_os("PATH") {
571///         let mut paths = env::split_paths(&path).collect::<Vec<_>>();
572///         paths.push(PathBuf::from("/home/xyz/bin"));
573///         let new_path = env::join_paths(paths)?;
574///         unsafe { env::set_var("PATH", &new_path); }
575///     }
576///
577///     Ok(())
578/// }
579/// ```
580///
581/// [`env::split_paths()`]: split_paths
582#[stable(feature = "env", since = "1.0.0")]
583pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
584where
585    I: IntoIterator<Item = T>,
586    T: AsRef<OsStr>,
587{
588    os_imp::join_paths(paths.into_iter()).map_err(|e| JoinPathsError { inner: e })
589}
590
591#[stable(feature = "env", since = "1.0.0")]
592impl fmt::Display for JoinPathsError {
593    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
594        self.inner.fmt(f)
595    }
596}
597
598#[stable(feature = "env", since = "1.0.0")]
599impl Error for JoinPathsError {
600    #[allow(deprecated, deprecated_in_future)]
601    fn description(&self) -> &str {
602        self.inner.description()
603    }
604}
605
606/// Returns the path of the current user's home directory if known.
607///
608/// This may return `None` if getting the directory fails or if the platform does not have user home directories.
609///
610/// For storing user data and configuration it is often preferable to use more specific directories.
611/// For example, [XDG Base Directories] on Unix or the `LOCALAPPDATA` and `APPDATA` environment variables on Windows.
612///
613/// [XDG Base Directories]: https://specifications.freedesktop.org/basedir-spec/latest/
614///
615/// # Unix
616///
617/// - Returns the value of the 'HOME' environment variable if it is set
618///   (including to an empty string).
619/// - Otherwise, it tries to determine the home directory by invoking the `getpwuid_r` function
620///   using the UID of the current user. An empty home directory field returned from the
621///   `getpwuid_r` function is considered to be a valid value.
622/// - Returns `None` if the current user has no entry in the /etc/passwd file.
623///
624/// # Windows
625///
626/// - Returns the value of the 'USERPROFILE' environment variable if it is set, and is not an empty string.
627/// - Otherwise, [`GetUserProfileDirectory`][msdn] is used to return the path. This may change in the future.
628///
629/// [msdn]: https://docs.microsoft.com/en-us/windows/win32/api/userenv/nf-userenv-getuserprofiledirectorya
630///
631/// In UWP (Universal Windows Platform) targets this function is unimplemented and always returns `None`.
632///
633/// Before Rust 1.85.0, this function used to return the value of the 'HOME' environment variable
634/// on Windows, which in Cygwin or Mingw environments could return non-standard paths like `/home/you`
635/// instead of `C:\Users\you`.
636///
637/// # Examples
638///
639/// ```
640/// use std::env;
641///
642/// match env::home_dir() {
643///     Some(path) => println!("Your home directory, probably: {}", path.display()),
644///     None => println!("Impossible to get your home dir!"),
645/// }
646/// ```
647#[must_use]
648#[stable(feature = "env", since = "1.0.0")]
649pub fn home_dir() -> Option<PathBuf> {
650    os_imp::home_dir()
651}
652
653/// Returns the path of a temporary directory.
654///
655/// The temporary directory may be shared among users, or between processes
656/// with different privileges; thus, the creation of any files or directories
657/// in the temporary directory must use a secure method to create a uniquely
658/// named file. Creating a file or directory with a fixed or predictable name
659/// may result in "insecure temporary file" security vulnerabilities. Consider
660/// using a crate that securely creates temporary files or directories.
661///
662/// Note that the returned value may be a symbolic link, not a directory.
663///
664/// # Platform-specific behavior
665///
666/// On Unix, returns the value of the `TMPDIR` environment variable if it is
667/// set, otherwise the value is OS-specific:
668/// - On Android, there is no global temporary folder (it is usually allocated
669///   per-app), it will return the application's cache dir if the program runs
670///   in application's namespace and system version is Android 13 (or above), or
671///   `/data/local/tmp` otherwise.
672/// - On Darwin-based OSes (macOS, iOS, etc) it returns the directory provided
673///   by `confstr(_CS_DARWIN_USER_TEMP_DIR, ...)`, as recommended by [Apple's
674///   security guidelines][appledoc].
675/// - On all other unix-based OSes, it returns `/tmp`.
676///
677/// On Windows, the behavior is equivalent to that of [`GetTempPath2`][GetTempPath2] /
678/// [`GetTempPath`][GetTempPath], which this function uses internally.
679///
680/// Note that, this [may change in the future][changes].
681///
682/// [changes]: io#platform-specific-behavior
683/// [GetTempPath2]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2a
684/// [GetTempPath]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha
685/// [appledoc]: https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/RaceConditions.html#//apple_ref/doc/uid/TP40002585-SW10
686///
687/// ```no_run
688/// use std::env;
689///
690/// fn main() {
691///     let dir = env::temp_dir();
692///     println!("Temporary directory: {}", dir.display());
693/// }
694/// ```
695#[must_use]
696#[doc(alias = "GetTempPath", alias = "GetTempPath2")]
697#[stable(feature = "env", since = "1.0.0")]
698pub fn temp_dir() -> PathBuf {
699    os_imp::temp_dir()
700}
701
702/// Returns the full filesystem path of the current running executable.
703///
704/// # Platform-specific behavior
705///
706/// If the executable was invoked through a symbolic link, some platforms will
707/// return the path of the symbolic link and other platforms will return the
708/// path of the symbolic link’s target.
709///
710/// If the executable is renamed while it is running, platforms may return the
711/// path at the time it was loaded instead of the new path.
712///
713/// # Errors
714///
715/// Acquiring the path of the current executable is a platform-specific operation
716/// that can fail for a good number of reasons. Some errors can include, but not
717/// be limited to, filesystem operations failing or general syscall failures.
718///
719/// # Security
720///
721/// The output of this function should not be trusted for anything
722/// that might have security implications. Basically, if users can run
723/// the executable, they can change the output arbitrarily.
724///
725/// As an example, you can easily introduce a race condition. It goes
726/// like this:
727///
728/// 1. You get the path to the current executable using `current_exe()`, and
729///    store it in a variable.
730/// 2. Time passes. A malicious actor removes the current executable, and
731///    replaces it with a malicious one.
732/// 3. You then use the stored path to re-execute the current
733///    executable.
734///
735/// You expected to safely execute the current executable, but you're
736/// instead executing something completely different. The code you
737/// just executed run with your privileges.
738///
739/// This sort of behavior has been known to [lead to privilege escalation] when
740/// used incorrectly.
741///
742/// [lead to privilege escalation]: https://securityvulns.com/Wdocument183.html
743///
744/// # Examples
745///
746/// ```
747/// use std::env;
748///
749/// match env::current_exe() {
750///     Ok(exe_path) => println!("Path of this executable is: {}",
751///                              exe_path.display()),
752///     Err(e) => println!("failed to get current exe path: {e}"),
753/// };
754/// ```
755#[stable(feature = "env", since = "1.0.0")]
756pub fn current_exe() -> io::Result<PathBuf> {
757    os_imp::current_exe()
758}
759
760/// An iterator over the arguments of a process, yielding a [`String`] value for
761/// each argument.
762///
763/// This struct is created by [`env::args()`]. See its documentation
764/// for more.
765///
766/// The first element is traditionally the path of the executable, but it can be
767/// set to arbitrary text, and might not even exist. This means this property
768/// should not be relied upon for security purposes.
769///
770/// [`env::args()`]: args
771#[must_use = "iterators are lazy and do nothing unless consumed"]
772#[stable(feature = "env", since = "1.0.0")]
773pub struct Args {
774    inner: ArgsOs,
775}
776
777/// An iterator over the arguments of a process, yielding an [`OsString`] value
778/// for each argument.
779///
780/// This struct is created by [`env::args_os()`]. See its documentation
781/// for more.
782///
783/// The first element is traditionally the path of the executable, but it can be
784/// set to arbitrary text, and might not even exist. This means this property
785/// should not be relied upon for security purposes.
786///
787/// [`env::args_os()`]: args_os
788#[must_use = "iterators are lazy and do nothing unless consumed"]
789#[stable(feature = "env", since = "1.0.0")]
790pub struct ArgsOs {
791    inner: sys::args::Args,
792}
793
794/// Returns the arguments that this program was started with (normally passed
795/// via the command line).
796///
797/// The first element is traditionally the path of the executable, but it can be
798/// set to arbitrary text, and might not even exist. This means this property should
799/// not be relied upon for security purposes.
800///
801/// On Unix systems the shell usually expands unquoted arguments with glob patterns
802/// (such as `*` and `?`). On Windows this is not done, and such arguments are
803/// passed as-is.
804///
805/// On glibc Linux systems, arguments are retrieved by placing a function in `.init_array`.
806/// glibc passes `argc`, `argv`, and `envp` to functions in `.init_array`, as a non-standard
807/// extension. This allows `std::env::args` to work even in a `cdylib` or `staticlib`, as it
808/// does on macOS and Windows.
809///
810/// # Panics
811///
812/// The returned iterator will panic during iteration if any argument to the
813/// process is not valid Unicode. If this is not desired,
814/// use the [`args_os`] function instead.
815///
816/// # Examples
817///
818/// ```
819/// use std::env;
820///
821/// // Prints each argument on a separate line
822/// for argument in env::args() {
823///     println!("{argument}");
824/// }
825/// ```
826#[stable(feature = "env", since = "1.0.0")]
827pub fn args() -> Args {
828    Args { inner: args_os() }
829}
830
831/// Returns the arguments that this program was started with (normally passed
832/// via the command line).
833///
834/// The first element is traditionally the path of the executable, but it can be
835/// set to arbitrary text, and might not even exist. This means this property should
836/// not be relied upon for security purposes.
837///
838/// On Unix systems the shell usually expands unquoted arguments with glob patterns
839/// (such as `*` and `?`). On Windows this is not done, and such arguments are
840/// passed as-is.
841///
842/// On glibc Linux systems, arguments are retrieved by placing a function in `.init_array`.
843/// glibc passes `argc`, `argv`, and `envp` to functions in `.init_array`, as a non-standard
844/// extension. This allows `std::env::args_os` to work even in a `cdylib` or `staticlib`, as it
845/// does on macOS and Windows.
846///
847/// Note that the returned iterator will not check if the arguments to the
848/// process are valid Unicode. If you want to panic on invalid UTF-8,
849/// use the [`args`] function instead.
850///
851/// # Examples
852///
853/// ```
854/// use std::env;
855///
856/// // Prints each argument on a separate line
857/// for argument in env::args_os() {
858///     println!("{argument:?}");
859/// }
860/// ```
861#[stable(feature = "env", since = "1.0.0")]
862pub fn args_os() -> ArgsOs {
863    ArgsOs { inner: sys::args::args() }
864}
865
866#[stable(feature = "env_unimpl_send_sync", since = "1.26.0")]
867impl !Send for Args {}
868
869#[stable(feature = "env_unimpl_send_sync", since = "1.26.0")]
870impl !Sync for Args {}
871
872#[stable(feature = "env", since = "1.0.0")]
873impl Iterator for Args {
874    type Item = String;
875    fn next(&mut self) -> Option<String> {
876        self.inner.next().map(|s| s.into_string().unwrap())
877    }
878    fn size_hint(&self) -> (usize, Option<usize>) {
879        self.inner.size_hint()
880    }
881}
882
883#[stable(feature = "env", since = "1.0.0")]
884impl ExactSizeIterator for Args {
885    fn len(&self) -> usize {
886        self.inner.len()
887    }
888    fn is_empty(&self) -> bool {
889        self.inner.is_empty()
890    }
891}
892
893#[stable(feature = "env_iterators", since = "1.12.0")]
894impl DoubleEndedIterator for Args {
895    fn next_back(&mut self) -> Option<String> {
896        self.inner.next_back().map(|s| s.into_string().unwrap())
897    }
898}
899
900#[stable(feature = "std_debug", since = "1.16.0")]
901impl fmt::Debug for Args {
902    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
903        let Self { inner: ArgsOs { inner } } = self;
904        f.debug_struct("Args").field("inner", inner).finish()
905    }
906}
907
908#[stable(feature = "env_unimpl_send_sync", since = "1.26.0")]
909impl !Send for ArgsOs {}
910
911#[stable(feature = "env_unimpl_send_sync", since = "1.26.0")]
912impl !Sync for ArgsOs {}
913
914#[stable(feature = "env", since = "1.0.0")]
915impl Iterator for ArgsOs {
916    type Item = OsString;
917    fn next(&mut self) -> Option<OsString> {
918        self.inner.next()
919    }
920    fn size_hint(&self) -> (usize, Option<usize>) {
921        self.inner.size_hint()
922    }
923}
924
925#[stable(feature = "env", since = "1.0.0")]
926impl ExactSizeIterator for ArgsOs {
927    fn len(&self) -> usize {
928        self.inner.len()
929    }
930    fn is_empty(&self) -> bool {
931        self.inner.is_empty()
932    }
933}
934
935#[stable(feature = "env_iterators", since = "1.12.0")]
936impl DoubleEndedIterator for ArgsOs {
937    fn next_back(&mut self) -> Option<OsString> {
938        self.inner.next_back()
939    }
940}
941
942#[stable(feature = "std_debug", since = "1.16.0")]
943impl fmt::Debug for ArgsOs {
944    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
945        let Self { inner } = self;
946        f.debug_struct("ArgsOs").field("inner", inner).finish()
947    }
948}
949
950/// Constants associated with the current target
951#[stable(feature = "env", since = "1.0.0")]
952pub mod consts {
953    use crate::sys::env::os;
954
955    /// A string describing the architecture of the CPU that is currently in use.
956    /// An example value may be: `"x86"`, `"arm"` or `"riscv64"`.
957    ///
958    /// <details><summary>Full list of possible values</summary>
959    ///
960    /// * `"x86"`
961    /// * `"x86_64"`
962    /// * `"arm"`
963    /// * `"aarch64"`
964    /// * `"m68k"`
965    /// * `"mips"`
966    /// * `"mips32r6"`
967    /// * `"mips64"`
968    /// * `"mips64r6"`
969    /// * `"csky"`
970    /// * `"powerpc"`
971    /// * `"powerpc64"`
972    /// * `"riscv32"`
973    /// * `"riscv64"`
974    /// * `"s390x"`
975    /// * `"sparc"`
976    /// * `"sparc64"`
977    /// * `"hexagon"`
978    /// * `"loongarch64"`
979    ///
980    /// </details>
981    #[stable(feature = "env", since = "1.0.0")]
982    pub const ARCH: &str = env!("STD_ENV_ARCH");
983
984    /// A string describing the family of the operating system.
985    /// An example value may be: `"unix"`, or `"windows"`.
986    ///
987    /// This value may be an empty string if the family is unknown.
988    ///
989    /// <details><summary>Full list of possible values</summary>
990    ///
991    /// * `"unix"`
992    /// * `"windows"`
993    /// * `"itron"`
994    /// * `"wasm"`
995    /// * `""`
996    ///
997    /// </details>
998    #[stable(feature = "env", since = "1.0.0")]
999    pub const FAMILY: &str = os::FAMILY;
1000
1001    /// A string describing the specific operating system in use.
1002    /// An example value may be: `"linux"`, or `"freebsd"`.
1003    ///
1004    /// <details><summary>Full list of possible values</summary>
1005    ///
1006    /// * `"linux"`
1007    /// * `"windows"`
1008    /// * `"macos"`
1009    /// * `"android"`
1010    /// * `"ios"`
1011    /// * `"openbsd"`
1012    /// * `"freebsd"`
1013    /// * `"netbsd"`
1014    /// * `"wasi"`
1015    /// * `"hermit"`
1016    /// * `"aix"`
1017    /// * `"apple"`
1018    /// * `"dragonfly"`
1019    /// * `"emscripten"`
1020    /// * `"espidf"`
1021    /// * `"fortanix"`
1022    /// * `"uefi"`
1023    /// * `"fuchsia"`
1024    /// * `"haiku"`
1025    /// * `"hermit"`
1026    /// * `"watchos"`
1027    /// * `"visionos"`
1028    /// * `"tvos"`
1029    /// * `"horizon"`
1030    /// * `"hurd"`
1031    /// * `"illumos"`
1032    /// * `"l4re"`
1033    /// * `"nto"`
1034    /// * `"redox"`
1035    /// * `"solaris"`
1036    /// * `"solid_asp3`
1037    /// * `"vita"`
1038    /// * `"vxworks"`
1039    /// * `"xous"`
1040    ///
1041    /// </details>
1042    #[stable(feature = "env", since = "1.0.0")]
1043    pub const OS: &str = os::OS;
1044
1045    /// Specifies the filename prefix, if any, used for shared libraries on this platform.
1046    /// This is either `"lib"` or an empty string. (`""`).
1047    #[stable(feature = "env", since = "1.0.0")]
1048    pub const DLL_PREFIX: &str = os::DLL_PREFIX;
1049
1050    /// Specifies the filename suffix, if any, used for shared libraries on this platform.
1051    /// An example value may be: `".so"`, `".elf"`, or `".dll"`.
1052    ///
1053    /// The possible values are identical to those of [`DLL_EXTENSION`], but with the leading period included.
1054    #[stable(feature = "env", since = "1.0.0")]
1055    pub const DLL_SUFFIX: &str = os::DLL_SUFFIX;
1056
1057    /// Specifies the file extension, if any, used for shared libraries on this platform that goes after the dot.
1058    /// An example value may be: `"so"`, `"elf"`, or `"dll"`.
1059    ///
1060    /// <details><summary>Full list of possible values</summary>
1061    ///
1062    /// * `"so"`
1063    /// * `"dylib"`
1064    /// * `"dll"`
1065    /// * `"sgxs"`
1066    /// * `"a"`
1067    /// * `"elf"`
1068    /// * `"wasm"`
1069    /// * `""` (an empty string)
1070    ///
1071    /// </details>
1072    #[stable(feature = "env", since = "1.0.0")]
1073    pub const DLL_EXTENSION: &str = os::DLL_EXTENSION;
1074
1075    /// Specifies the filename suffix, if any, used for executable binaries on this platform.
1076    /// An example value may be: `".exe"`, or `".efi"`.
1077    ///
1078    /// The possible values are identical to those of [`EXE_EXTENSION`], but with the leading period included.
1079    #[stable(feature = "env", since = "1.0.0")]
1080    pub const EXE_SUFFIX: &str = os::EXE_SUFFIX;
1081
1082    /// Specifies the file extension, if any, used for executable binaries on this platform.
1083    /// An example value may be: `"exe"`, or an empty string (`""`).
1084    ///
1085    /// <details><summary>Full list of possible values</summary>
1086    ///
1087    /// * `"exe"`
1088    /// * `"efi"`
1089    /// * `"js"`
1090    /// * `"sgxs"`
1091    /// * `"elf"`
1092    /// * `"wasm"`
1093    /// * `""` (an empty string)
1094    ///
1095    /// </details>
1096    #[stable(feature = "env", since = "1.0.0")]
1097    pub const EXE_EXTENSION: &str = os::EXE_EXTENSION;
1098}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy