@@ -8,34 +8,282 @@ use anyhow::Context;
88
99
1010
11- pub fn current_dir_wc ( ) -> crate :: rewrite_output_type ! ( std :: io :: Result < std :: path :: PathBuf > ) {
12- std :: env :: current_dir ( )
13- . with_context ( || crate :: call_failed!( None :: <( ) >, "std::env::current_dir" ) )
14- }
15- pub fn current_exe_wc ( ) -> crate :: rewrite_output_type ! ( std :: io :: Result < std :: path :: PathBuf > ) {
16- std :: env :: current_exe ( )
17- . with_context ( || crate :: call_failed!( None :: <( ) >, "std::env::current_exe" ) )
18- }
19- pub fn home_dir_wc ( ) -> crate :: rewrite_output_type ! ( core :: option :: Option < std :: path :: PathBuf > ) {
20- std :: env :: home_dir ( )
21- . with_context ( || crate :: call_failed!( None :: <( ) >, "std::env::home_dir" ) )
22- }
23- pub fn join_paths_wc < I , T > ( paths : I ) -> crate :: rewrite_output_type ! ( core :: result :: Result < std :: ffi :: OsString , std :: env :: JoinPathsError > ) where I : core :: iter :: IntoIterator < Item = T > , T : core :: convert :: AsRef < std :: ffi :: OsStr > {
24- std :: env :: join_paths ( paths)
25- . with_context ( || crate :: call_failed!( None :: <( ) >, "std::env::join_paths" , crate :: CustomDebugMessage ( "value of type impl IntoIterator" ) ) )
26- }
11+ /// Changes the current working directory to the specified path.
12+ ///
13+ /// # Platform-specific behavior
14+ ///
15+ /// This function [currently] corresponds to the `chdir` function on Unix
16+ /// and the `SetCurrentDirectoryW` function on Windows.
17+ ///
18+ /// Returns an [`Err`] if the operation fails.
19+ ///
20+ /// [currently]: crate::io#platform-specific-behavior
21+ ///
22+ /// # Examples
23+ ///
24+ /// ```
25+ /// use std::env;
26+ /// use std::path::Path;
27+ ///
28+ /// let root = Path::new("/");
29+ /// assert!(env::set_current_dir(&root).is_ok());
30+ /// println!("Successfully changed working directory to {}!", root.display());
31+ /// ```
2732pub fn set_current_dir_wc < P : core :: convert :: AsRef < std :: path :: Path > > ( path : P ) -> crate :: rewrite_output_type ! ( std :: io :: Result < ( ) > ) {
2833 let path = path. as_ref ( ) ;
2934 std :: env :: set_current_dir ( path)
3035 . with_context ( || crate :: call_failed!( None :: <( ) >, "std::env::set_current_dir" , path) )
3136}
37+ /// Fetches the environment variable `key` from the current process, returning
38+ /// [`None`] if the variable isn't set or if there is another error.
39+ ///
40+ /// It may return `None` if the environment variable's name contains
41+ /// the equal sign character (`=`) or the NUL character.
42+ ///
43+ /// Note that this function will not check if the environment variable
44+ /// is valid Unicode. If you want to have an error on invalid UTF-8,
45+ /// use the [`var`] function instead.
46+ ///
47+ /// # Examples
48+ ///
49+ /// ```
50+ /// use std::env;
51+ ///
52+ /// let key = "HOME";
53+ /// match env::var_os(key) {
54+ /// Some(val) => println!("{key}: {val:?}"),
55+ /// None => println!("{key} is not defined in the environment.")
56+ /// }
57+ /// ```
58+ ///
59+ /// If expecting a delimited variable (such as `PATH`), [`split_paths`]
60+ /// can be used to separate items.
3261pub fn var_os_wc < K : core :: convert :: AsRef < std :: ffi :: OsStr > > ( key : K ) -> crate :: rewrite_output_type ! ( core :: option :: Option < std :: ffi :: OsString > ) {
3362 let key = key. as_ref ( ) ;
3463 std :: env :: var_os ( key)
3564 . with_context ( || crate :: call_failed!( None :: <( ) >, "std::env::var_os" , key) )
3665}
66+ /// Fetches the environment variable `key` from the current process.
67+ ///
68+ /// # Errors
69+ ///
70+ /// Returns [`VarError::NotPresent`] if:
71+ /// - The variable is not set.
72+ /// - The variable's name contains an equal sign or NUL (`'='` or `'\0'`).
73+ ///
74+ /// Returns [`VarError::NotUnicode`] if the variable's value is not valid
75+ /// Unicode. If this is not desired, consider using [`var_os`].
76+ ///
77+ /// # Examples
78+ ///
79+ /// ```
80+ /// use std::env;
81+ ///
82+ /// let key = "HOME";
83+ /// match env::var(key) {
84+ /// Ok(val) => println!("{key}: {val:?}"),
85+ /// Err(e) => println!("couldn't interpret {key}: {e}"),
86+ /// }
87+ /// ```
3788pub fn var_wc < K : core :: convert :: AsRef < std :: ffi :: OsStr > > ( key : K ) -> crate :: rewrite_output_type ! ( core :: result :: Result < std :: string :: String , std :: env :: VarError > ) {
3889 let key = key. as_ref ( ) ;
3990 std :: env :: var ( key)
4091 . with_context ( || crate :: call_failed!( None :: <( ) >, "std::env::var" , key) )
4192}
93+ /// Joins a collection of [`Path`]s appropriately for the `PATH`
94+ /// environment variable.
95+ ///
96+ /// # Errors
97+ ///
98+ /// Returns an [`Err`] (containing an error message) if one of the input
99+ /// [`Path`]s contains an invalid character for constructing the `PATH`
100+ /// variable (a double quote on Windows or a colon on Unix), or if the system
101+ /// does not have a `PATH`-like variable (e.g. UEFI or WASI).
102+ ///
103+ /// # Examples
104+ ///
105+ /// Joining paths on a Unix-like platform:
106+ ///
107+ /// ```
108+ /// use std::env;
109+ /// use std::ffi::OsString;
110+ /// use std::path::Path;
111+ ///
112+ /// fn main() -> Result<(), env::JoinPathsError> {
113+ /// # if cfg!(unix) {
114+ /// let paths = [Path::new("/bin"), Path::new("/usr/bin")];
115+ /// let path_os_string = env::join_paths(paths.iter())?;
116+ /// assert_eq!(path_os_string, OsString::from("/bin:/usr/bin"));
117+ /// # }
118+ /// Ok(())
119+ /// }
120+ /// ```
121+ ///
122+ /// Joining a path containing a colon on a Unix-like platform results in an
123+ /// error:
124+ ///
125+ /// ```
126+ /// # if cfg!(unix) {
127+ /// use std::env;
128+ /// use std::path::Path;
129+ ///
130+ /// let paths = [Path::new("/bin"), Path::new("/usr/bi:n")];
131+ /// assert!(env::join_paths(paths.iter()).is_err());
132+ /// # }
133+ /// ```
134+ ///
135+ /// Using `env::join_paths()` with [`env::split_paths()`] to append an item to
136+ /// the `PATH` environment variable:
137+ ///
138+ /// ```
139+ /// use std::env;
140+ /// use std::path::PathBuf;
141+ ///
142+ /// fn main() -> Result<(), env::JoinPathsError> {
143+ /// if let Some(path) = env::var_os("PATH") {
144+ /// let mut paths = env::split_paths(&path).collect::<Vec<_>>();
145+ /// paths.push(PathBuf::from("/home/xyz/bin"));
146+ /// let new_path = env::join_paths(paths)?;
147+ /// env::set_var("PATH", &new_path);
148+ /// }
149+ ///
150+ /// Ok(())
151+ /// }
152+ /// ```
153+ ///
154+ /// [`env::split_paths()`]: split_paths
155+ pub fn join_paths_wc < I , T > ( paths : I ) -> crate :: rewrite_output_type ! ( core :: result :: Result < std :: ffi :: OsString , std :: env :: JoinPathsError > ) where I : core :: iter :: IntoIterator < Item = T > , T : core :: convert :: AsRef < std :: ffi :: OsStr > {
156+ std :: env :: join_paths ( paths)
157+ . with_context ( || crate :: call_failed!( None :: <( ) >, "std::env::join_paths" , crate :: CustomDebugMessage ( "value of type impl IntoIterator" ) ) )
158+ }
159+ /// Returns the current working directory as a [`PathBuf`].
160+ ///
161+ /// # Platform-specific behavior
162+ ///
163+ /// This function [currently] corresponds to the `getcwd` function on Unix
164+ /// and the `GetCurrentDirectoryW` function on Windows.
165+ ///
166+ /// [currently]: crate::io#platform-specific-behavior
167+ ///
168+ /// # Errors
169+ ///
170+ /// Returns an [`Err`] if the current working directory value is invalid.
171+ /// Possible cases:
172+ ///
173+ /// * Current directory does not exist.
174+ /// * There are insufficient permissions to access the current directory.
175+ ///
176+ /// # Examples
177+ ///
178+ /// ```
179+ /// use std::env;
180+ ///
181+ /// fn main() -> std::io::Result<()> {
182+ /// let path = env::current_dir()?;
183+ /// println!("The current directory is {}", path.display());
184+ /// Ok(())
185+ /// }
186+ /// ```
187+ pub fn current_dir_wc ( ) -> crate :: rewrite_output_type ! ( std :: io :: Result < std :: path :: PathBuf > ) {
188+ std :: env :: current_dir ( )
189+ . with_context ( || crate :: call_failed!( None :: <( ) >, "std::env::current_dir" ) )
190+ }
191+ /// Returns the full filesystem path of the current running executable.
192+ ///
193+ /// # Platform-specific behavior
194+ ///
195+ /// If the executable was invoked through a symbolic link, some platforms will
196+ /// return the path of the symbolic link and other platforms will return the
197+ /// path of the symbolic link’s target.
198+ ///
199+ /// If the executable is renamed while it is running, platforms may return the
200+ /// path at the time it was loaded instead of the new path.
201+ ///
202+ /// # Errors
203+ ///
204+ /// Acquiring the path of the current executable is a platform-specific operation
205+ /// that can fail for a good number of reasons. Some errors can include, but not
206+ /// be limited to, filesystem operations failing or general syscall failures.
207+ ///
208+ /// # Security
209+ ///
210+ /// The output of this function should not be trusted for anything
211+ /// that might have security implications. Basically, if users can run
212+ /// the executable, they can change the output arbitrarily.
213+ ///
214+ /// As an example, you can easily introduce a race condition. It goes
215+ /// like this:
216+ ///
217+ /// 1. You get the path to the current executable using `current_exe()`, and
218+ /// store it in a variable.
219+ /// 2. Time passes. A malicious actor removes the current executable, and
220+ /// replaces it with a malicious one.
221+ /// 3. You then use the stored path to re-execute the current
222+ /// executable.
223+ ///
224+ /// You expected to safely execute the current executable, but you're
225+ /// instead executing something completely different. The code you
226+ /// just executed run with your privileges.
227+ ///
228+ /// This sort of behavior has been known to [lead to privilege escalation] when
229+ /// used incorrectly.
230+ ///
231+ /// [lead to privilege escalation]: https://securityvulns.com/Wdocument183.html
232+ ///
233+ /// # Examples
234+ ///
235+ /// ```
236+ /// use std::env;
237+ ///
238+ /// match env::current_exe() {
239+ /// Ok(exe_path) => println!("Path of this executable is: {}",
240+ /// exe_path.display()),
241+ /// Err(e) => println!("failed to get current exe path: {e}"),
242+ /// };
243+ /// ```
244+ pub fn current_exe_wc ( ) -> crate :: rewrite_output_type ! ( std :: io :: Result < std :: path :: PathBuf > ) {
245+ std :: env :: current_exe ( )
246+ . with_context ( || crate :: call_failed!( None :: <( ) >, "std::env::current_exe" ) )
247+ }
248+ /// Returns the path of the current user's home directory if known.
249+ ///
250+ /// # Unix
251+ ///
252+ /// - Returns the value of the 'HOME' environment variable if it is set
253+ /// (including to an empty string).
254+ /// - Otherwise, it tries to determine the home directory by invoking the `getpwuid_r` function
255+ /// using the UID of the current user. An empty home directory field returned from the
256+ /// `getpwuid_r` function is considered to be a valid value.
257+ /// - Returns `None` if the current user has no entry in the /etc/passwd file.
258+ ///
259+ /// # Windows
260+ ///
261+ /// - Returns the value of the 'HOME' environment variable if it is set
262+ /// (including to an empty string).
263+ /// - Otherwise, returns the value of the 'USERPROFILE' environment variable if it is set
264+ /// (including to an empty string).
265+ /// - If both do not exist, [`GetUserProfileDirectory`][msdn] is used to return the path.
266+ ///
267+ /// [msdn]: https://docs.microsoft.com/en-us/windows/win32/api/userenv/nf-userenv-getuserprofiledirectorya
268+ ///
269+ /// # Deprecation
270+ ///
271+ /// This function is deprecated because the behaviour on Windows is not correct.
272+ /// The 'HOME' environment variable is not standard on Windows, and may not produce
273+ /// desired results; for instance, under Cygwin or Mingw it will return `/home/you`
274+ /// when it should return `C:\Users\you`.
275+ ///
276+ /// # Examples
277+ ///
278+ /// ```
279+ /// use std::env;
280+ ///
281+ /// match env::home_dir() {
282+ /// Some(path) => println!("Your home directory, probably: {}", path.display()),
283+ /// None => println!("Impossible to get your home dir!"),
284+ /// }
285+ /// ```
286+ pub fn home_dir_wc ( ) -> crate :: rewrite_output_type ! ( core :: option :: Option < std :: path :: PathBuf > ) {
287+ std :: env :: home_dir ( )
288+ . with_context ( || crate :: call_failed!( None :: <( ) >, "std::env::home_dir" ) )
289+ }
0 commit comments