about summary refs log tree commit diff
path: root/src/libstd/sys/unix
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-07-10 11:07:25 +0000
committerbors <bors@rust-lang.org>2015-07-10 11:07:25 +0000
commitd0d37075a54b68df99c46d42655a06c575eecd3f (patch)
tree03a0f0e30444469beca4f346f495b368ed37d2d2 /src/libstd/sys/unix
parent4695fbde2157d1a172cea5df99bd661c4aa1204a (diff)
parent1d202692ecfddb4b731993a5db4271c8698cbade (diff)
downloadrust-d0d37075a54b68df99c46d42655a06c575eecd3f.tar.gz
rust-d0d37075a54b68df99c46d42655a06c575eecd3f.zip
Auto merge of #26751 - retep998:copy-that-floppy, r=alexcrichton
Using the OS mechanism for copying files allows the OS to optimize the transfer using stuff such as [Offloaded Data Transfers (ODX)](https://msdn.microsoft.com/en-us/library/windows/desktop/hh848056%28v=vs.85%29.aspx).
Also preserves a lot more information, including NTFS [File Streams](https://msdn.microsoft.com/en-us/library/windows/desktop/aa364404%28v=vs.85%29.aspx), which the manual implementation threw away.
In addition, it is an atomic operation, unlike the manual implementation which has extra calls for copying over permissions.

r? @alexcrichton 
Diffstat (limited to 'src/libstd/sys/unix')
-rw-r--r--src/libstd/sys/unix/fs.rs18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 7396d088ade..8113d0ea847 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -14,7 +14,7 @@ use os::unix::prelude::*;
 
 use ffi::{CString, CStr, OsString, OsStr};
 use fmt;
-use io::{self, Error, SeekFrom};
+use io::{self, Error, ErrorKind, SeekFrom};
 use libc::{self, c_int, size_t, off_t, c_char, mode_t};
 use mem;
 use path::{Path, PathBuf};
@@ -516,3 +516,19 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
     buf.truncate(p);
     Ok(PathBuf::from(OsString::from_vec(buf)))
 }
+
+pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
+    use fs::{File, PathExt, set_permissions};
+    if !from.is_file() {
+        return Err(Error::new(ErrorKind::InvalidInput,
+                              "the source path is not an existing file"))
+    }
+
+    let mut reader = try!(File::open(from));
+    let mut writer = try!(File::create(to));
+    let perm = try!(reader.metadata()).permissions();
+
+    let ret = try!(io::copy(&mut reader, &mut writer));
+    try!(set_permissions(to, perm));
+    Ok(ret)
+}