diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index fe9a81bb7c9..26cb4f917c5 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -40,6 +40,7 @@ #![feature(staged_api)] #![feature(std_misc)] #![feature(unicode)] +#![feature(os)] #![cfg_attr(test, feature(test))] extern crate arena; diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index d63b3dd60d0..a8d39f95739 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -14,6 +14,7 @@ pub use self::FileMatch::*; use std::collections::HashSet; use std::env; +use std::os; use std::old_io::fs::PathExtensions; use std::old_io::fs; @@ -194,7 +195,7 @@ pub fn get_or_default_sysroot() -> Path { }) } - match canonicalize(env::current_exe().ok()) { + match canonicalize(os::self_exe_name()) { Some(mut p) => { p.pop(); p.pop(); p } None => panic!("can't determine value for sysroot") } @@ -224,7 +225,7 @@ pub fn rust_path() -> Vec { } None => Vec::new() }; - let mut cwd = env::current_dir().unwrap(); + let mut cwd = os::getcwd().unwrap(); // now add in default entries let cwd_dot_rust = cwd.join(".rust"); if !env_rust_path.contains(&cwd_dot_rust) { @@ -243,7 +244,7 @@ pub fn rust_path() -> Vec { } cwd.pop(); } - if let Some(h) = env::home_dir() { + if let Some(h) = os::homedir() { let p = h.join(".rust"); if !env_rust_path.contains(&p) && p.exists() { env_rust_path.push(p); diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs index b3bc898748f..a419d4134b4 100644 --- a/src/librustc/plugin/load.rs +++ b/src/librustc/plugin/load.rs @@ -15,7 +15,7 @@ use metadata::creader::CrateReader; use plugin::registry::Registry; use std::mem; -use std::env; +use std::os; use std::dynamic_lib::DynamicLibrary; use std::borrow::ToOwned; use syntax::ast; @@ -103,7 +103,7 @@ impl<'a> PluginLoader<'a> { path: Path, symbol: String) -> PluginRegistrarFun { // Make sure the path contains a / or the linker will search for it. - let path = env::current_dir().unwrap().join(&path); + let path = os::getcwd().unwrap().join(&path); let lib = match DynamicLibrary::open(Some(&path)) { Ok(lib) => lib, diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index b690cc7f7d0..615ee77c1e0 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -27,8 +27,8 @@ use syntax::{ast, codemap}; use rustc_back::target::Target; -use std::env; use std::cell::{Cell, RefCell}; +use std::os; pub mod config; pub mod search_paths; @@ -347,7 +347,7 @@ pub fn build_session_(sopts: config::Options, if path.is_absolute() { path.clone() } else { - env::current_dir().unwrap().join(&path) + os::getcwd().unwrap().join(&path) } ); @@ -370,7 +370,7 @@ pub fn build_session_(sopts: config::Options, plugin_registrar_fn: Cell::new(None), default_sysroot: default_sysroot, local_crate_source_file: local_crate_source_file, - working_dir: env::current_dir().unwrap(), + working_dir: os::getcwd().unwrap(), lint_store: RefCell::new(lint::LintStore::new()), lints: RefCell::new(NodeMap()), crate_types: RefCell::new(Vec::new()), diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs index 6bf745315ea..3fcae6a8034 100644 --- a/src/librustc_back/archive.rs +++ b/src/librustc_back/archive.rs @@ -14,7 +14,7 @@ use std::old_io::fs::PathExtensions; use std::old_io::process::{Command, ProcessOutput}; use std::old_io::{fs, TempDir}; use std::old_io; -use std::env; +use std::os; use std::str; use syntax::diagnostic::Handler as ErrorHandler; @@ -224,7 +224,7 @@ impl<'a> ArchiveBuilder<'a> { pub fn build(self) -> Archive<'a> { // Get an absolute path to the destination, so `ar` will work even // though we run it from `self.work_dir`. - let abs_dst = env::current_dir().unwrap().join(&self.archive.dst); + let abs_dst = os::getcwd().unwrap().join(&self.archive.dst); assert!(!abs_dst.is_relative()); let mut args = vec![&abs_dst]; let mut total_len = abs_dst.as_vec().len(); @@ -283,7 +283,7 @@ impl<'a> ArchiveBuilder<'a> { // First, extract the contents of the archive to a temporary directory. // We don't unpack directly into `self.work_dir` due to the possibility // of filename collisions. - let archive = env::current_dir().unwrap().join(archive); + let archive = os::getcwd().unwrap().join(archive); run_ar(self.archive.handler, &self.archive.maybe_ar_prog, "x", Some(loc.path()), &[&archive]); diff --git a/src/librustc_back/fs.rs b/src/librustc_back/fs.rs index acf49d1ca46..99a1df95a80 100644 --- a/src/librustc_back/fs.rs +++ b/src/librustc_back/fs.rs @@ -10,13 +10,13 @@ use std::old_io; use std::old_io::fs; -use std::env; +use std::os; /// Returns an absolute path in the filesystem that `path` points to. The /// returned path does not contain any symlinks in its hierarchy. pub fn realpath(original: &Path) -> old_io::IoResult { static MAX_LINKS_FOLLOWED: uint = 256; - let original = try!(env::current_dir()).join(original); + let original = try!(os::getcwd()).join(original); // Right now lstat on windows doesn't work quite well if cfg!(windows) { diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index d589b063204..711f937d2f3 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -41,6 +41,7 @@ #![feature(rustc_private)] #![feature(staged_api)] #![feature(env)] +#![feature(path)] extern crate syntax; extern crate serialize; diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs index 3f2dcee5110..943ff52925a 100644 --- a/src/librustc_back/rpath.rs +++ b/src/librustc_back/rpath.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - use std::collections::HashSet; use std::env; use std::old_io::IoError; +use std::os; use syntax::ast; pub struct RPathConfig where @@ -109,7 +109,7 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path "$ORIGIN" }; - let cwd = env::current_dir().unwrap(); + let cwd = os::getcwd().unwrap(); let mut lib = (config.realpath)(&cwd.join(lib)).unwrap(); lib.pop(); let mut output = (config.realpath)(&cwd.join(&config.out_filename)).unwrap(); @@ -129,7 +129,7 @@ fn get_install_prefix_rpath(config: RPathConfig) -> String where let path = (config.get_install_prefix_lib_path)(); let path = env::current_dir().unwrap().join(&path); // FIXME (#9639): This needs to handle non-utf8 paths - path.as_str().expect("non-utf8 component in rpath").to_string() + path.to_str().expect("non-utf8 component in rpath").to_string() } fn minimize_rpaths(rpaths: &[String]) -> Vec { diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index b04c07977c3..d09a7c355d3 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -310,6 +310,7 @@ impl Target { /// JSON decoding. pub fn search(target: &str) -> Result { use std::env; + use std::os; use std::ffi::OsString; use std::old_io::File; use std::old_path::Path; @@ -396,7 +397,7 @@ impl Target { // FIXME 16351: add a sane default search path? - for dir in env::split_paths(&target_path) { + for dir in os::split_paths(target_path.to_str().unwrap()).iter() { let p = dir.join(path.clone()); if p.is_file() { return load_file(&p); diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index b12f05d7c50..a1a0e71f334 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -32,6 +32,7 @@ use super::Compilation; use serialize::json; use std::env; +use std::os; use std::ffi::OsString; use std::old_io::fs; use std::old_io; @@ -471,7 +472,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, if cfg!(windows) { _old_path = env::var_os("PATH").unwrap_or(_old_path); let mut new_path = sess.host_filesearch(PathKind::All).get_dylib_search_paths(); - new_path.extend(env::split_paths(&_old_path)); + new_path.extend(os::split_paths(_old_path.to_str().unwrap()).into_iter()); env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap()); } let features = sess.features.borrow(); @@ -738,7 +739,7 @@ pub fn phase_6_link_output(sess: &Session, outputs: &OutputFilenames) { let old_path = env::var_os("PATH").unwrap_or(OsString::from_str("")); let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(); - new_path.extend(env::split_paths(&old_path)); + new_path.extend(os::split_paths(old_path.to_str().unwrap()).into_iter()); env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap()); time(sess.time_passes(), "linking", (), |_| diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index bf14b86ebd1..78f126dcf6a 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -13,7 +13,7 @@ use std::sync::mpsc::channel; use std::dynamic_lib::DynamicLibrary; use std::old_io::{Command, TempDir}; use std::old_io; -use std::env; +use std::os; use std::str; use std::thread; use std::thunk::Thunk; @@ -46,7 +46,7 @@ pub fn run(input: &str, let input = config::Input::File(input_path.clone()); let sessopts = config::Options { - maybe_sysroot: Some(env::current_exe().unwrap().dir_path().dir_path()), + maybe_sysroot: Some(os::self_exe_name().unwrap().dir_path().dir_path()), search_paths: libs.clone(), crate_types: vec!(config::CrateTypeDylib), externs: externs.clone(), @@ -113,7 +113,7 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths, let input = config::Input::Str(test.to_string()); let sessopts = config::Options { - maybe_sysroot: Some(env::current_exe().unwrap().dir_path().dir_path()), + maybe_sysroot: Some(os::self_exe_name().unwrap().dir_path().dir_path()), search_paths: libs, crate_types: vec!(config::CrateTypeExecutable), output_types: vec!(config::OutputTypeExe), diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs index fcae8e79160..babae3b3019 100644 --- a/src/libstd/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -21,6 +21,7 @@ use ffi::CString; use mem; use env; use str; +use os; pub struct DynamicLibrary { handle: *mut u8 @@ -102,7 +103,7 @@ impl DynamicLibrary { /// process pub fn search_path() -> Vec { match env::var_os(DynamicLibrary::envvar()) { - Some(var) => env::split_paths(&var).collect(), + Some(var) => os::split_paths(var.to_str().unwrap()), None => Vec::new(), } } diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 0e1f5f2ba02..5db9f6ef7fd 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -21,7 +21,8 @@ use prelude::v1::*; use error::Error; use ffi::{OsString, AsOsStr}; use fmt; -use old_io::IoResult; +use io; +use path::{AsPath, PathBuf}; use sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT, Ordering}; use sync::{StaticMutex, MUTEX_INIT}; use sys::os as os_imp; @@ -46,7 +47,7 @@ use sys::os as os_imp; /// let p = env::current_dir().unwrap(); /// println!("The current directory is {}", p.display()); /// ``` -pub fn current_dir() -> IoResult { +pub fn current_dir() -> io::Result { os_imp::getcwd() } @@ -57,14 +58,14 @@ pub fn current_dir() -> IoResult { /// /// ```rust /// use std::env; -/// use std::old_path::Path; +/// use std::path::Path; /// /// let root = Path::new("/"); /// assert!(env::set_current_dir(&root).is_ok()); /// println!("Successfully changed working directory to {}!", root.display()); /// ``` -pub fn set_current_dir(p: &Path) -> IoResult<()> { - os_imp::chdir(p) +pub fn set_current_dir(p: &P) -> io::Result<()> { + os_imp::chdir(p.as_path()) } static ENV_LOCK: StaticMutex = MUTEX_INIT; @@ -280,8 +281,8 @@ pub fn split_paths(unparsed: &T) -> SplitPaths { } impl<'a> Iterator for SplitPaths<'a> { - type Item = Path; - fn next(&mut self) -> Option { self.inner.next() } + type Item = PathBuf; + fn next(&mut self) -> Option { self.inner.next() } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } @@ -305,10 +306,11 @@ pub struct JoinPathsError { /// /// ```rust /// use std::env; +/// use std::path::PathBuf; /// /// if let Some(path) = env::var_os("PATH") { /// let mut paths = env::split_paths(&path).collect::>(); -/// paths.push(Path::new("/home/xyz/bin")); +/// paths.push(PathBuf::new("/home/xyz/bin")); /// let new_path = env::join_paths(paths.iter()).unwrap(); /// env::set_var("PATH", &new_path); /// } @@ -355,7 +357,7 @@ impl Error for JoinPathsError { /// None => println!("Impossible to get your home dir!") /// } /// ``` -pub fn home_dir() -> Option { +pub fn home_dir() -> Option { os_imp::home_dir() } @@ -369,7 +371,7 @@ pub fn home_dir() -> Option { /// On Windows, returns the value of, in order, the 'TMP', 'TEMP', /// 'USERPROFILE' environment variable if any are set and not the empty /// string. Otherwise, tmpdir returns the path to the Windows directory. -pub fn temp_dir() -> Path { +pub fn temp_dir() -> PathBuf { os_imp::temp_dir() } @@ -396,7 +398,7 @@ pub fn temp_dir() -> Path { /// Err(e) => println!("failed to get current exe path: {}", e), /// }; /// ``` -pub fn current_exe() -> IoResult { +pub fn current_exe() -> io::Result { os_imp::current_exe() } @@ -825,6 +827,7 @@ mod tests { use iter::repeat; use rand::{self, Rng}; use ffi::{OsString, OsStr}; + use path::PathBuf; fn make_rand_name() -> OsString { let mut rng = rand::thread_rng(); @@ -944,7 +947,7 @@ mod tests { fn split_paths_unix() { fn check_parse(unparsed: &str, parsed: &[&str]) -> bool { split_paths(unparsed).collect::>() == - parsed.iter().map(|s| Path::new(*s)).collect::>() + parsed.iter().map(|s| PathBuf::new(*s)).collect::>() } assert!(check_parse("", &mut [""])); diff --git a/src/libstd/fs.rs b/src/libstd/fs/mod.rs similarity index 99% rename from src/libstd/fs.rs rename to src/libstd/fs/mod.rs index 98c1b50a9bf..aa211758621 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs/mod.rs @@ -25,6 +25,10 @@ use sys::fs2 as fs_imp; use sys_common::{AsInnerMut, FromInner, AsInner}; use vec::Vec; +pub use self::tempdir::TempDir; + +mod tempdir; + /// A reference to an open file on the filesystem. /// /// An instance of a `File` can be read and/or written depending on what options diff --git a/src/libstd/fs/tempdir.rs b/src/libstd/fs/tempdir.rs new file mode 100644 index 00000000000..79bdb35dd48 --- /dev/null +++ b/src/libstd/fs/tempdir.rs @@ -0,0 +1,125 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![unstable(feature = "tempdir", reason = "needs an RFC before stabilization")] + +use prelude::v1::*; + +use env; +use io::{self, Error, ErrorKind}; +use fs; +use path::{self, PathBuf, AsPath}; +use rand::{thread_rng, Rng}; + +/// A wrapper for a path to temporary directory implementing automatic +/// scope-based deletion. +pub struct TempDir { + path: Option, +} + +// How many times should we (re)try finding an unused random name? It should be +// enough that an attacker will run out of luck before we run out of patience. +const NUM_RETRIES: u32 = 1 << 31; +// How many characters should we include in a random file name? It needs to +// be enough to dissuade an attacker from trying to preemptively create names +// of that length, but not so huge that we unnecessarily drain the random number +// generator of entropy. +const NUM_RAND_CHARS: uint = 12; + +impl TempDir { + /// Attempts to make a temporary directory inside of `tmpdir` whose name + /// will have the prefix `prefix`. The directory will be automatically + /// deleted once the returned wrapper is destroyed. + /// + /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] // rand usage + pub fn new_in(tmpdir: &P, prefix: &str) + -> io::Result { + let storage; + let mut tmpdir = tmpdir.as_path(); + if !tmpdir.is_absolute() { + let cur_dir = try!(env::current_dir()); + storage = cur_dir.join(tmpdir); + tmpdir = &storage; + // return TempDir::new_in(&cur_dir.join(tmpdir), prefix); + } + + let mut rng = thread_rng(); + for _ in 0..NUM_RETRIES { + let suffix: String = rng.gen_ascii_chars().take(NUM_RAND_CHARS).collect(); + let leaf = if prefix.len() > 0 { + format!("{}.{}", prefix, suffix) + } else { + // If we're given an empty string for a prefix, then creating a + // directory starting with "." would lead to it being + // semi-invisible on some systems. + suffix + }; + let path = tmpdir.join(&leaf); + match fs::create_dir(&path) { + Ok(_) => return Ok(TempDir { path: Some(path) }), + Err(ref e) if e.kind() == ErrorKind::PathAlreadyExists => {} + Err(e) => return Err(e) + } + } + + Err(Error::new(ErrorKind::PathAlreadyExists, + "too many temporary directories already exist", + None)) + } + + /// Attempts to make a temporary directory inside of `env::temp_dir()` whose + /// name will have the prefix `prefix`. The directory will be automatically + /// deleted once the returned wrapper is destroyed. + /// + /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] + pub fn new(prefix: &str) -> io::Result { + TempDir::new_in(&env::temp_dir(), prefix) + } + + /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper. + /// This discards the wrapper so that the automatic deletion of the + /// temporary directory is prevented. + pub fn into_path(mut self) -> PathBuf { + self.path.take().unwrap() + } + + /// Access the wrapped `std::path::Path` to the temporary directory. + pub fn path(&self) -> &path::Path { + self.path.as_ref().unwrap() + } + + /// Close and remove the temporary directory + /// + /// Although `TempDir` removes the directory on drop, in the destructor + /// any errors are ignored. To detect errors cleaning up the temporary + /// directory, call `close` instead. + pub fn close(mut self) -> io::Result<()> { + self.cleanup_dir() + } + + fn cleanup_dir(&mut self) -> io::Result<()> { + match self.path { + Some(ref p) => fs::remove_dir_all(p), + None => Ok(()) + } + } +} + +impl Drop for TempDir { + fn drop(&mut self) { + let _ = self.cleanup_dir(); + } +} + +// the tests for this module need to change the path using change_dir, +// and this doesn't play nicely with other tests so these unit tests are located +// in src/test/run-pass/tempfile.rs diff --git a/src/libstd/net/test.rs b/src/libstd/net/test.rs index c70e92884ac..aec50d638c6 100644 --- a/src/libstd/net/test.rs +++ b/src/libstd/net/test.rs @@ -34,6 +34,6 @@ fn base_port() -> u16 { let dirs = ["32-opt", "32-nopt", "64-opt", "64-nopt", "64-opt-vg", "all-opt", "snap3", "dist"]; dirs.iter().enumerate().find(|&(_, dir)| { - cwd.as_str().unwrap().contains(dir) + cwd.to_str().unwrap().contains(dir) }).map(|p| p.0).unwrap_or(0) as u16 * 1000 + 19600 } diff --git a/src/libstd/old_io/tempfile.rs b/src/libstd/old_io/tempfile.rs index 42317c7a2d4..76753dca52e 100644 --- a/src/libstd/old_io/tempfile.rs +++ b/src/libstd/old_io/tempfile.rs @@ -96,9 +96,10 @@ impl TempDir { /// deleted once the returned wrapper is destroyed. /// /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] pub fn new_in(tmpdir: &Path, prefix: &str) -> IoResult { if !tmpdir.is_absolute() { - let cur_dir = try!(env::current_dir()); + let cur_dir = try!(::os::getcwd()); return TempDir::new_in(&cur_dir.join(tmpdir), prefix); } @@ -132,8 +133,9 @@ impl TempDir { /// deleted once the returned wrapper is destroyed. /// /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] pub fn new(prefix: &str) -> IoResult { - TempDir::new_in(&env::temp_dir(), prefix) + TempDir::new_in(&::os::tmpdir(), prefix) } /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper. diff --git a/src/libstd/old_io/test.rs b/src/libstd/old_io/test.rs index ee72beccfa8..43c0b9268a2 100644 --- a/src/libstd/old_io/test.rs +++ b/src/libstd/old_io/test.rs @@ -38,10 +38,11 @@ fn next_test_unix_socket() -> String { /// Get a temporary path which could be the location of a unix socket #[cfg(not(target_os = "ios"))] +#[allow(deprecated)] pub fn next_test_unix() -> Path { let string = next_test_unix_socket(); if cfg!(unix) { - env::temp_dir().join(string) + ::os::tmpdir().join(string) } else { Path::new(format!("{}{}", r"\\.\pipe\", string)) } @@ -88,7 +89,7 @@ fn base_port() -> u16 { // FIXME (#9639): This needs to handle non-utf8 paths let path = env::current_dir().unwrap(); - let path_s = path.as_str().unwrap(); + let path_s = path.to_str().unwrap(); let mut final_base = base; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 86f5c2c356e..9c42d1be77e 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -49,6 +49,7 @@ use ops::{Drop, FnOnce}; use option::Option::{Some, None}; use option::Option; use old_path::{Path, GenericPath, BytesContainer}; +use path::{self, PathBuf}; use ptr::PtrExt; use ptr; use result::Result::{Err, Ok}; @@ -67,6 +68,35 @@ use vec::Vec; #[cfg(unix)] pub use sys::ext as unix; #[cfg(windows)] pub use sys::ext as windows; +fn err2old(new: ::io::Error) -> IoError { + IoError { + kind: ::old_io::OtherIoError, + desc: "os error", + detail: Some(new.to_string()), + } +} + +#[cfg(windows)] +fn path2new(path: &Path) -> PathBuf { + PathBuf::new(path.as_str().unwrap()) +} +#[cfg(unix)] +fn path2new(path: &Path) -> PathBuf { + use os::unix::prelude::*; + PathBuf::new(::from_bytes(path.as_vec())) +} + +#[cfg(unix)] +fn path2old(path: &path::Path) -> Path { + use os::unix::prelude::*; + use ffi::AsOsStr; + Path::new(path.as_os_str().as_bytes()) +} +#[cfg(windows)] +fn path2old(path: &path::Path) -> Path { + Path::new(path.to_str().unwrap()) +} + /// Get the number of cores available pub fn num_cpus() -> uint { unsafe { @@ -100,10 +130,9 @@ pub const TMPBUF_SZ : uint = 1000; /// let current_working_directory = os::getcwd().unwrap(); /// println!("The current directory is {:?}", current_working_directory.display()); /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to std::env::current_dir")] #[unstable(feature = "os")] pub fn getcwd() -> IoResult { - env::current_dir() + env::current_dir().map_err(err2old).map(|s| path2old(&s)) } /// Returns a vector of (variable, value) pairs, for all the environment @@ -245,12 +274,11 @@ pub fn unsetenv(n: &str) { /// None => println!("{} is not defined in the environment.", key) /// } /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to env::split_paths")] #[unstable(feature = "os")] pub fn split_paths(unparsed: T) -> Vec { let b = unparsed.container_as_bytes(); let s = str::from_utf8(b).unwrap(); - env::split_paths(s).collect() + env::split_paths(s).map(|s| path2old(&s)).collect() } /// Joins a collection of `Path`s appropriately for the `PATH` @@ -274,7 +302,6 @@ pub fn split_paths(unparsed: T) -> Vec { /// paths.push(Path::new("/home/xyz/bin")); /// os::setenv(key, os::join_paths(paths.as_slice()).unwrap()); /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to env::join_paths")] #[unstable(feature = "os")] pub fn join_paths(paths: &[T]) -> Result, &'static str> { env::join_paths(paths.iter().map(|s| { @@ -335,10 +362,9 @@ pub fn dll_filename(base: &str) -> String { /// None => println!("Unable to get the path of this executable!") /// }; /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to env::current_exe")] #[unstable(feature = "os")] pub fn self_exe_name() -> Option { - env::current_exe().ok() + env::current_exe().ok().map(|p| path2old(&p)) } /// Optionally returns the filesystem path to the current executable which is @@ -356,10 +382,9 @@ pub fn self_exe_name() -> Option { /// None => println!("Impossible to fetch the path of this executable.") /// }; /// ``` -#[deprecated(since = "1.0.0", reason = "use env::current_exe + dir_path/pop")] #[unstable(feature = "os")] pub fn self_exe_path() -> Option { - env::current_exe().ok().map(|mut p| { p.pop(); p }) + env::current_exe().ok().map(|p| { let mut p = path2old(&p); p.pop(); p }) } /// Optionally returns the path to the current user's home directory if known. @@ -386,9 +411,8 @@ pub fn self_exe_path() -> Option { /// None => println!("Impossible to get your home dir!") /// } /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to env::home_dir")] -#[allow(deprecated)] #[unstable(feature = "os")] +#[allow(deprecated)] pub fn homedir() -> Option { #[inline] #[cfg(unix)] @@ -424,9 +448,8 @@ pub fn homedir() -> Option { /// On Windows, returns the value of, in order, the 'TMP', 'TEMP', /// 'USERPROFILE' environment variable if any are set and not the empty /// string. Otherwise, tmpdir returns the path to the Windows directory. -#[deprecated(since = "1.0.0", reason = "renamed to env::temp_dir")] -#[allow(deprecated)] #[unstable(feature = "os")] +#[allow(deprecated)] pub fn tmpdir() -> Path { return lookup(); @@ -488,7 +511,8 @@ pub fn make_absolute(p: &Path) -> IoResult { if p.is_absolute() { Ok(p.clone()) } else { - env::current_dir().map(|mut cwd| { + env::current_dir().map_err(err2old).map(|cwd| { + let mut cwd = path2old(&cwd); cwd.push(p); cwd }) @@ -507,10 +531,9 @@ pub fn make_absolute(p: &Path) -> IoResult { /// assert!(os::change_dir(&root).is_ok()); /// println!("Successfully changed working directory to {}!", root.display()); /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to env::set_current_dir")] #[unstable(feature = "os")] pub fn change_dir(p: &Path) -> IoResult<()> { - return sys::os::chdir(p); + sys::os::chdir(&path2new(p)).map_err(err2old) } /// Returns the platform-specific value of errno diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs index 6f07dea5279..6267792ba74 100644 --- a/src/libstd/sys/unix/backtrace.rs +++ b/src/libstd/sys/unix/backtrace.rs @@ -84,8 +84,9 @@ /// all unix platforms we support right now, so it at least gets the job done. use prelude::v1::*; +use os::unix::prelude::*; -use ffi::CStr; +use ffi::{CStr, AsOsStr}; use old_io::IoResult; use libc; use mem; @@ -327,7 +328,7 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> { }; let filename = match selfname { Some(path) => { - let bytes = path.as_vec(); + let bytes = path.as_os_str().as_bytes(); if bytes.len() < LAST_FILENAME.len() { let i = bytes.iter(); for (slot, val) in LAST_FILENAME.iter_mut().zip(i) { diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index d51f907307e..951c091f9f3 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -16,12 +16,13 @@ use os::unix::*; use error::Error as StdError; use ffi::{CString, CStr, OsString, OsStr, AsOsStr}; use fmt; +use io; use iter; use libc::{self, c_int, c_char, c_void}; use mem; -use io; -use old_io::{IoResult, IoError, fs}; +use old_io::{IoError, IoResult}; use ptr; +use path::{self, PathBuf}; use slice; use str; use sys::c; @@ -32,6 +33,14 @@ use vec; const BUF_BYTES: usize = 2048; const TMPBUF_SZ: usize = 128; +fn bytes2path(b: &[u8]) -> PathBuf { + PathBuf::new(::from_bytes(b)) +} + +fn os2path(os: OsString) -> PathBuf { + bytes2path(os.as_bytes()) +} + /// Returns the platform-specific value of errno pub fn errno() -> i32 { #[cfg(any(target_os = "macos", @@ -102,30 +111,30 @@ pub fn error_string(errno: i32) -> String { } } -pub fn getcwd() -> IoResult { +pub fn getcwd() -> io::Result { let mut buf = [0 as c_char; BUF_BYTES]; unsafe { if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() { - Err(IoError::last_error()) + Err(io::Error::last_os_error()) } else { - Ok(Path::new(CStr::from_ptr(buf.as_ptr()).to_bytes())) + Ok(bytes2path(CStr::from_ptr(buf.as_ptr()).to_bytes())) } } } -pub fn chdir(p: &Path) -> IoResult<()> { - let p = CString::new(p.as_vec()).unwrap(); +pub fn chdir(p: &path::Path) -> io::Result<()> { + let p = try!(CString::new(p.as_os_str().as_bytes())); unsafe { match libc::chdir(p.as_ptr()) == (0 as c_int) { true => Ok(()), - false => Err(IoError::last_error()), + false => Err(io::Error::last_os_error()), } } } pub struct SplitPaths<'a> { iter: iter::Map bool>, - fn(&'a [u8]) -> Path>, + fn(&'a [u8]) -> PathBuf>, } pub fn split_paths<'a>(unparsed: &'a OsStr) -> SplitPaths<'a> { @@ -133,13 +142,13 @@ pub fn split_paths<'a>(unparsed: &'a OsStr) -> SplitPaths<'a> { let unparsed = unparsed.as_bytes(); SplitPaths { iter: unparsed.split(is_colon as fn(&u8) -> bool) - .map(Path::new as fn(&'a [u8]) -> Path) + .map(bytes2path as fn(&'a [u8]) -> PathBuf) } } impl<'a> Iterator for SplitPaths<'a> { - type Item = Path; - fn next(&mut self) -> Option { self.iter.next() } + type Item = PathBuf; + fn next(&mut self) -> Option { self.iter.next() } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } @@ -200,12 +209,12 @@ pub fn current_exe() -> IoResult { } #[cfg(target_os = "dragonfly")] -pub fn current_exe() -> IoResult { - fs::readlink(&Path::new("/proc/curproc/file")) +pub fn current_exe() -> io::Result { + ::fs::read_link("/proc/curproc/file") } #[cfg(any(target_os = "bitrig", target_os = "openbsd"))] -pub fn current_exe() -> IoResult { +pub fn current_exe() -> io::Result { use sync::{StaticMutex, MUTEX_INIT}; static LOCK: StaticMutex = MUTEX_INIT; @@ -226,8 +235,8 @@ pub fn current_exe() -> IoResult { } #[cfg(any(target_os = "linux", target_os = "android"))] -pub fn current_exe() -> IoResult { - fs::readlink(&Path::new("/proc/self/exe")) +pub fn current_exe() -> io::Result { + ::fs::read_link("/proc/self/exe") } #[cfg(any(target_os = "macos", target_os = "ios"))] @@ -451,22 +460,20 @@ pub fn page_size() -> usize { } } -pub fn temp_dir() -> Path { - getenv("TMPDIR".as_os_str()).map(|p| Path::new(p.into_vec())).unwrap_or_else(|| { +pub fn temp_dir() -> PathBuf { + getenv("TMPDIR".as_os_str()).map(os2path).unwrap_or_else(|| { if cfg!(target_os = "android") { - Path::new("/data/local/tmp") + PathBuf::new("/data/local/tmp") } else { - Path::new("/tmp") + PathBuf::new("/tmp") } }) } -pub fn home_dir() -> Option { +pub fn home_dir() -> Option { return getenv("HOME".as_os_str()).or_else(|| unsafe { fallback() - }).map(|os| { - Path::new(os.into_vec()) - }); + }).map(os2path); #[cfg(any(target_os = "android", target_os = "ios"))] diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index 304d7e01532..309d6c9dc48 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -368,7 +368,9 @@ pub fn readlink(p: &Path) -> IoResult { buf as *const u16, sz - 1, libc::VOLUME_NAME_DOS) - }, super::os2path); + }, |data| { + Path::new(String::from_utf16(data).unwrap()) + }); assert!(unsafe { libc::CloseHandle(handle) } != 0); return ret; } diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index a756fb29f81..51df18d504d 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -14,13 +14,14 @@ use prelude::v1::*; -use ffi::OsStr; +use ffi::{OsStr, OsString}; use io::{self, ErrorKind}; use libc; use mem; -use old_io::{self, IoResult, IoError}; use num::Int; -use os::windows::OsStrExt; +use old_io::{self, IoResult, IoError}; +use os::windows::{OsStrExt, OsStringExt}; +use path::PathBuf; use sync::{Once, ONCE_INIT}; macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => ( @@ -314,9 +315,10 @@ fn fill_utf16_buf_new(f1: F1, f2: F2) -> io::Result fill_utf16_buf_base(f1, f2).map_err(|()| io::Error::last_os_error()) } -fn os2path(s: &[u16]) -> Path { - // FIXME: this should not be a panicking conversion (aka path reform) - Path::new(String::from_utf16(s).unwrap()) +fn os2path(s: &[u16]) -> PathBuf { + let os = ::from_wide(s); + // FIXME(#22751) should consume `os` + PathBuf::new(&os) } pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] { diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 6520d30487c..587ab7924fd 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -18,11 +18,13 @@ use os::windows::*; use error::Error as StdError; use ffi::{OsString, OsStr, AsOsStr}; use fmt; -use ops::Range; +use io; use libc::types::os::arch::extra::LPWCH; use libc::{self, c_int, c_void}; use mem; use old_io::{IoError, IoResult}; +use ops::Range; +use path::{self, PathBuf}; use ptr; use slice; use sys::c; @@ -151,8 +153,8 @@ pub fn split_paths(unparsed: &OsStr) -> SplitPaths { } impl<'a> Iterator for SplitPaths<'a> { - type Item = Path; - fn next(&mut self) -> Option { + type Item = PathBuf; + fn next(&mut self) -> Option { // On Windows, the PATH environment variable is semicolon separated. // Double quotes are used as a way of introducing literal semicolons // (since c:\some;dir is a valid Windows path). Double quotes are not @@ -186,7 +188,7 @@ impl<'a> Iterator for SplitPaths<'a> { if !must_yield && in_progress.is_empty() { None } else { - Some(super::os2path(&in_progress[..])) + Some(super::os2path(&in_progress)) } } } @@ -228,33 +230,33 @@ impl StdError for JoinPathsError { fn description(&self) -> &str { "failed to join paths" } } -pub fn current_exe() -> IoResult { - super::fill_utf16_buf(|buf, sz| unsafe { +pub fn current_exe() -> io::Result { + super::fill_utf16_buf_new(|buf, sz| unsafe { libc::GetModuleFileNameW(ptr::null_mut(), buf, sz) }, super::os2path) } -pub fn getcwd() -> IoResult { - super::fill_utf16_buf(|buf, sz| unsafe { +pub fn getcwd() -> io::Result { + super::fill_utf16_buf_new(|buf, sz| unsafe { libc::GetCurrentDirectoryW(sz, buf) }, super::os2path) } -pub fn chdir(p: &Path) -> IoResult<()> { +pub fn chdir(p: &path::Path) -> io::Result<()> { let mut p = p.as_os_str().encode_wide().collect::>(); p.push(0); unsafe { match libc::SetCurrentDirectoryW(p.as_ptr()) != (0 as libc::BOOL) { true => Ok(()), - false => Err(IoError::last_error()), + false => Err(io::Error::last_os_error()), } } } pub fn getenv(k: &OsStr) -> Option { let k = super::to_utf16_os(k); - super::fill_utf16_buf(|buf, sz| unsafe { + super::fill_utf16_buf_new(|buf, sz| unsafe { libc::GetEnvironmentVariableW(k.as_ptr(), buf, sz) }, |buf| { OsStringExt::from_wide(buf) @@ -349,18 +351,18 @@ pub unsafe fn pipe() -> IoResult<(FileDesc, FileDesc)> { } } -pub fn temp_dir() -> Path { - super::fill_utf16_buf(|buf, sz| unsafe { +pub fn temp_dir() -> PathBuf { + super::fill_utf16_buf_new(|buf, sz| unsafe { c::GetTempPathW(sz, buf) }, super::os2path).unwrap() } -pub fn home_dir() -> Option { +pub fn home_dir() -> Option { getenv("HOME".as_os_str()).or_else(|| { getenv("USERPROFILE".as_os_str()) }).map(|os| { - // FIXME: OsString => Path - Path::new(os.to_str().unwrap()) + // FIXME(#22751) should consume `os` + PathBuf::new(&os) }).or_else(|| unsafe { let me = c::GetCurrentProcess(); let mut token = ptr::null_mut(); @@ -368,7 +370,7 @@ pub fn home_dir() -> Option { return None } let _handle = RawHandle::new(token); - super::fill_utf16_buf(|buf, mut sz| { + super::fill_utf16_buf_new(|buf, mut sz| { match c::GetUserProfileDirectoryW(token, buf, &mut sz) { 0 if libc::GetLastError() != 0 => 0, 0 => sz, diff --git a/src/libstd/sys/windows/process2.rs b/src/libstd/sys/windows/process2.rs index 19e38196d19..d4c6e85489f 100644 --- a/src/libstd/sys/windows/process2.rs +++ b/src/libstd/sys/windows/process2.rs @@ -16,16 +16,15 @@ use collections; use env; use ffi::{OsString, OsStr}; use fmt; +use fs; use io::{self, Error}; use libc::{self, c_void}; -use old_io::fs; -use old_path; use os::windows::OsStrExt; use ptr; use sync::{StaticMutex, MUTEX_INIT}; +use sys::handle::Handle; use sys::pipe2::AnonPipe; use sys::{self, cvt}; -use sys::handle::Handle; use sys_common::{AsInner, FromInner}; //////////////////////////////////////////////////////////////////////////////// @@ -142,9 +141,8 @@ impl Process { for path in split_paths(&v) { let path = path.join(cfg.program.to_str().unwrap()) .with_extension(env::consts::EXE_EXTENSION); - // FIXME: update with new fs module once it lands - if fs::stat(&old_path::Path::new(&path)).is_ok() { - return Some(OsString::from_str(path.as_str().unwrap())) + if fs::metadata(&path).is_ok() { + return Some(path.into_os_string()) } } break diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 5418533aff1..823d2879236 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -60,6 +60,7 @@ #![feature(unicode)] #![feature(std_misc)] #![feature(env)] +#![feature(os)] #![cfg_attr(windows, feature(libc))] #[macro_use] extern crate log; diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs index c40a5534efb..a0cd7842070 100644 --- a/src/libterm/terminfo/searcher.rs +++ b/src/libterm/terminfo/searcher.rs @@ -17,12 +17,13 @@ use std::old_io::fs::PathExtensions; use std::env; /// Return path to database entry for `term` +#[allow(deprecated)] pub fn get_dbpath_for_term(term: &str) -> Option> { if term.len() == 0 { return None; } - let homedir = env::home_dir(); + let homedir = ::std::os::homedir(); let mut dirs_to_search = Vec::new(); let first_char = term.char_at(0); diff --git a/src/test/run-pass/env-home-dir.rs b/src/test/run-pass/env-home-dir.rs index 0e1ab73c02d..2ab6feaf782 100644 --- a/src/test/run-pass/env-home-dir.rs +++ b/src/test/run-pass/env-home-dir.rs @@ -9,13 +9,14 @@ // except according to those terms. use std::env::*; +use std::path::PathBuf; #[cfg(unix)] fn main() { let oldhome = var("HOME"); set_var("HOME", "/home/MountainView"); - assert!(home_dir() == Some(Path::new("/home/MountainView"))); + assert!(home_dir() == Some(PathBuf::new("/home/MountainView"))); remove_var("HOME"); if cfg!(target_os = "android") { diff --git a/src/test/run-pass/issue-15149.rs b/src/test/run-pass/issue-15149.rs index aa176d5b0f0..d995ecc492e 100644 --- a/src/test/run-pass/issue-15149.rs +++ b/src/test/run-pass/issue-15149.rs @@ -1,5 +1,3 @@ -// no-prefer-dynamic - // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. @@ -10,12 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::slice::SliceExt; -use std::old_io::{fs, USER_RWX}; -use std::process; +// no-prefer-dynamic + +#![feature(fs, process, env, path, rand)] + use std::env; -use std::old_path::BytesContainer; +use std::fs; +use std::process; use std::rand::random; +use std::str; fn main() { // If we're the child, make sure we were invoked correctly @@ -34,21 +35,20 @@ fn main() { fn test() { // If we're the parent, copy our own binary to a new directory. let my_path = env::current_exe().unwrap(); - let my_dir = my_path.dir_path(); + let my_dir = my_path.parent().unwrap(); let random_u32: u32 = random(); - let child_dir = Path::new(my_dir.join(format!("issue-15149-child-{}", - random_u32))); - fs::mkdir(&child_dir, USER_RWX).unwrap(); + let child_dir = my_dir.join(&format!("issue-15149-child-{}", random_u32)); + fs::create_dir(&child_dir).unwrap(); - let child_path = child_dir.join(format!("mytest{}", - env::consts::EXE_SUFFIX)); + let child_path = child_dir.join(&format!("mytest{}", + env::consts::EXE_SUFFIX)); fs::copy(&my_path, &child_path).unwrap(); // Append the new directory to our own PATH. let path = { let mut paths: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap()).collect(); - paths.push(child_dir.clone()); + paths.push(child_dir.to_path_buf()); env::join_paths(paths.iter()).unwrap() }; @@ -58,9 +58,9 @@ fn test() { assert!(child_output.status.success(), format!("child assertion failed\n child stdout:\n {}\n child stderr:\n {}", - child_output.stdout.container_as_str().unwrap(), - child_output.stderr.container_as_str().unwrap())); + str::from_utf8(&child_output.stdout).unwrap(), + str::from_utf8(&child_output.stderr).unwrap())); - fs::rmdir_recursive(&child_dir).unwrap(); + fs::remove_dir_all(&child_dir).unwrap(); } diff --git a/src/test/run-pass/issue-16272.rs b/src/test/run-pass/issue-16272.rs index 3bab78ab0df..92d8dfa2cf9 100644 --- a/src/test/run-pass/issue-16272.rs +++ b/src/test/run-pass/issue-16272.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::old_io::{process, Command}; +use std::process::Command; use std::env; fn main() { @@ -22,10 +22,8 @@ fn main() { } fn test() { - let status = Command::new(env::current_exe().unwrap()) + let status = Command::new(&env::current_exe().unwrap()) .arg("foo").arg("") - .stdout(process::InheritFd(1)) - .stderr(process::InheritFd(2)) .status().unwrap(); assert!(status.success()); } diff --git a/src/test/run-pass/issue-20091.rs b/src/test/run-pass/issue-20091.rs index 4d20e6360ad..ba107dd2cf9 100644 --- a/src/test/run-pass/issue-20091.rs +++ b/src/test/run-pass/issue-20091.rs @@ -8,14 +8,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-windows currently windows requires UTF-8 for spawning processes - -use std::old_io::Command; -use std::env; - +#[cfg(unix)] fn main() { + use std::process::Command; + use std::env; + use std::os::unix::prelude::*; + use std::ffi::OsStr; + if env::args().len() == 1 { - assert!(Command::new(env::current_exe().unwrap()).arg(b"\xff") + assert!(Command::new(&env::current_exe().unwrap()) + .arg(::from_bytes(b"\xff")) .status().unwrap().success()) } } + +#[cfg(windows)] +fn main() {}