about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-04-27 17:29:35 -0700
committerAlex Crichton <alex@alexcrichton.com>2015-04-28 17:38:26 -0700
commit0368abb0a420620c65c9662dcd4322c0276c209e (patch)
treedc5de77e6d2eb997cbc2e42f3de88d3e2a4be0e9
parent9348700007c6ac913df97c8e9e1ab7df6f91f130 (diff)
downloadrust-0368abb0a420620c65c9662dcd4322c0276c209e.tar.gz
rust-0368abb0a420620c65c9662dcd4322c0276c209e.zip
std: Implement fs::DirBuilder
This is the last remaining portion of #24796
-rw-r--r--src/librustc_trans/back/link.rs2
-rw-r--r--src/libstd/fs.rs62
-rw-r--r--src/libstd/sys/unix/ext/fs.rs16
-rw-r--r--src/libstd/sys/unix/fs2.rs24
-rw-r--r--src/libstd/sys/windows/fs2.rs18
5 files changed, 104 insertions, 18 deletions
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index bc26495b76b..4dd92b04da5 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -864,7 +864,7 @@ fn link_args(cmd: &mut Command,
     // target descriptor
     let t = &sess.target.target;
 
-    cmd.arg("-L").arg(&lib_path);
+    cmd.arg("-L").arg(&fix_windows_verbatim_for_gcc(&lib_path));
 
     cmd.arg("-o").arg(out_filename).arg(obj_filename);
 
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index b47c0c696bf..2b15a4ff83e 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -152,6 +152,15 @@ pub struct Permissions(fs_imp::FilePermissions);
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct FileType(fs_imp::FileType);
 
+/// A builder used to create directories in various manners.
+///
+/// This builder also supports platform-specific options.
+#[unstable(feature = "dir_builder", reason = "recently added API")]
+pub struct DirBuilder {
+    inner: fs_imp::DirBuilder,
+    recursive: bool,
+}
+
 impl File {
     /// Attempts to open a file in read-only mode.
     ///
@@ -997,7 +1006,7 @@ pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
-    fs_imp::mkdir(path.as_ref())
+    DirBuilder::new().create(path.as_ref())
 }
 
 /// Recursively create a directory and all of its parent components if they
@@ -1022,10 +1031,7 @@ pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
-    let path = path.as_ref();
-    if path == Path::new("") || path.is_dir() { return Ok(()) }
-    if let Some(p) = path.parent() { try!(create_dir_all(p)) }
-    create_dir(path)
+    DirBuilder::new().recursive(true).create(path.as_ref())
 }
 
 /// Removes an existing, empty directory.
@@ -1286,6 +1292,52 @@ pub fn set_permissions<P: AsRef<Path>>(path: P, perm: Permissions) -> io::Result
     fs_imp::set_perm(path.as_ref(), perm.0)
 }
 
+impl DirBuilder {
+    /// Creates a new set of options with default mode/security settings for all
+    /// platforms and also non-recursive.
+    pub fn new() -> DirBuilder {
+        DirBuilder {
+            inner: fs_imp::DirBuilder::new(),
+            recursive: false,
+        }
+    }
+
+    /// Indicate that directories create should be created recursively, creating
+    /// all parent directories if they do not exist with the same security and
+    /// permissions settings.
+    ///
+    /// This option defaults to `false`
+    pub fn recursive(&mut self, recursive: bool) -> &mut Self {
+        self.recursive = recursive;
+        self
+    }
+
+    /// Create the specified directory with the options configured in this
+    /// builder.
+    pub fn create<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
+        let path = path.as_ref();
+        if self.recursive {
+            self.create_dir_all(path)
+        } else {
+            self.inner.mkdir(path)
+        }
+    }
+
+    fn create_dir_all(&self, path: &Path) -> io::Result<()> {
+        if path == Path::new("") || path.is_dir() { return Ok(()) }
+        if let Some(p) = path.parent() {
+            try!(self.create_dir_all(p))
+        }
+        self.inner.mkdir(path)
+    }
+}
+
+impl AsInnerMut<fs_imp::DirBuilder> for DirBuilder {
+    fn as_inner_mut(&mut self) -> &mut fs_imp::DirBuilder {
+        &mut self.inner
+    }
+}
+
 #[cfg(test)]
 mod tests {
     #![allow(deprecated)] //rand
diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs
index ad6a856d5bc..2e4ed38e50f 100644
--- a/src/libstd/sys/unix/ext/fs.rs
+++ b/src/libstd/sys/unix/ext/fs.rs
@@ -189,3 +189,19 @@ pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
 {
     sys::fs2::symlink(src.as_ref(), dst.as_ref())
 }
+
+#[unstable(feature = "dir_builder", reason = "recently added API")]
+/// An extension trait for `fs::DirBuilder` for unix-specific options.
+pub trait DirBuilderExt {
+    /// Sets the mode to create new directories with. This option defaults to
+    /// 0o777.
+    fn mode(&mut self, mode: raw::mode_t) -> &mut Self;
+}
+
+impl DirBuilderExt for fs::DirBuilder {
+    fn mode(&mut self, mode: raw::mode_t) -> &mut fs::DirBuilder {
+        self.as_inner_mut().set_mode(mode);
+        self
+    }
+}
+
diff --git a/src/libstd/sys/unix/fs2.rs b/src/libstd/sys/unix/fs2.rs
index 678d8065ce7..350161c751c 100644
--- a/src/libstd/sys/unix/fs2.rs
+++ b/src/libstd/sys/unix/fs2.rs
@@ -61,6 +61,8 @@ pub struct FilePermissions { mode: mode_t }
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct FileType { mode: mode_t }
 
+pub struct DirBuilder { mode: mode_t }
+
 impl FileAttr {
     pub fn size(&self) -> u64 { self.stat.st_size as u64 }
     pub fn perm(&self) -> FilePermissions {
@@ -342,6 +344,22 @@ impl File {
     pub fn fd(&self) -> &FileDesc { &self.0 }
 }
 
+impl DirBuilder {
+    pub fn new() -> DirBuilder {
+        DirBuilder { mode: 0o777 }
+    }
+
+    pub fn mkdir(&self, p: &Path) -> io::Result<()> {
+        let p = try!(cstr(p));
+        try!(cvt(unsafe { libc::mkdir(p.as_ptr(), self.mode) }));
+        Ok(())
+    }
+
+    pub fn set_mode(&mut self, mode: mode_t) {
+        self.mode = mode;
+    }
+}
+
 fn cstr(path: &Path) -> io::Result<CString> {
     path.as_os_str().to_cstring().ok_or(
         io::Error::new(io::ErrorKind::InvalidInput, "path contained a null"))
@@ -401,12 +419,6 @@ impl fmt::Debug for File {
     }
 }
 
-pub fn mkdir(p: &Path) -> io::Result<()> {
-    let p = try!(cstr(p));
-    try!(cvt(unsafe { libc::mkdir(p.as_ptr(), 0o777) }));
-    Ok(())
-}
-
 pub fn readdir(p: &Path) -> io::Result<ReadDir> {
     let root = Arc::new(p.to_path_buf());
     let p = try!(cstr(p));
diff --git a/src/libstd/sys/windows/fs2.rs b/src/libstd/sys/windows/fs2.rs
index 2c81c34d3a4..5b748280986 100644
--- a/src/libstd/sys/windows/fs2.rs
+++ b/src/libstd/sys/windows/fs2.rs
@@ -70,6 +70,8 @@ pub struct OpenOptions {
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct FilePermissions { attrs: libc::DWORD }
 
+pub struct DirBuilder;
+
 impl Iterator for ReadDir {
     type Item = io::Result<DirEntry>;
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
@@ -425,12 +427,16 @@ impl FileType {
     pub fn is_symlink(&self) -> bool { *self == FileType::Symlink }
 }
 
-pub fn mkdir(p: &Path) -> io::Result<()> {
-    let p = to_utf16(p);
-    try!(cvt(unsafe {
-        libc::CreateDirectoryW(p.as_ptr(), ptr::null_mut())
-    }));
-    Ok(())
+impl DirBuilder {
+    pub fn new() -> DirBuilder { DirBuilder }
+
+    pub fn mkdir(&self, p: &Path) -> io::Result<()> {
+        let p = to_utf16(p);
+        try!(cvt(unsafe {
+            libc::CreateDirectoryW(p.as_ptr(), ptr::null_mut())
+        }));
+        Ok(())
+    }
 }
 
 pub fn readdir(p: &Path) -> io::Result<ReadDir> {