diff options
| author | Peter Atashian <retep998@gmail.com> | 2015-07-10 04:54:00 -0400 |
|---|---|---|
| committer | Peter Atashian <retep998@gmail.com> | 2015-07-10 04:54:00 -0400 |
| commit | 1d202692ecfddb4b731993a5db4271c8698cbade (patch) | |
| tree | 34287c51a624f75750215bc208d0ef74bc8a8ead /src/libstd/sys | |
| parent | e6a9be10bc1b178dc0b23c505fc8f17e925cabb2 (diff) | |
| download | rust-1d202692ecfddb4b731993a5db4271c8698cbade.tar.gz rust-1d202692ecfddb4b731993a5db4271c8698cbade.zip | |
Use CopyFileEx for fs::copy on Windows
Adds a couple more tests for fs::copy Signed-off-by: Peter Atashian <retep998@gmail.com>
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/unix/fs.rs | 18 | ||||
| -rw-r--r-- | src/libstd/sys/windows/c.rs | 24 | ||||
| -rw-r--r-- | src/libstd/sys/windows/fs.rs | 25 |
3 files changed, 66 insertions, 1 deletions
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 128284834ab..991e62b4ebb 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) +} diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index 2ddf685729b..16563be2cfb 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -66,6 +66,11 @@ pub const STD_ERROR_HANDLE: libc::DWORD = -12i32 as libc::DWORD; pub const HANDLE_FLAG_INHERIT: libc::DWORD = 0x00000001; +pub const PROGRESS_CONTINUE: libc::DWORD = 0; +pub const PROGRESS_CANCEL: libc::DWORD = 1; +pub const PROGRESS_STOP: libc::DWORD = 2; +pub const PROGRESS_QUIET: libc::DWORD = 3; + #[repr(C)] #[cfg(target_arch = "x86")] pub struct WSADATA { @@ -249,6 +254,19 @@ pub type PCONDITION_VARIABLE = *mut CONDITION_VARIABLE; pub type PSRWLOCK = *mut SRWLOCK; pub type ULONG = c_ulong; pub type ULONG_PTR = c_ulong; +pub type LPBOOL = *mut BOOL; + +pub type LPPROGRESS_ROUTINE = ::option::Option<unsafe extern "system" fn( + TotalFileSize: libc::LARGE_INTEGER, + TotalBytesTransferred: libc::LARGE_INTEGER, + StreamSize: libc::LARGE_INTEGER, + StreamBytesTransferred: libc::LARGE_INTEGER, + dwStreamNumber: DWORD, + dwCallbackReason: DWORD, + hSourceFile: HANDLE, + hDestinationFile: HANDLE, + lpData: LPVOID, +) -> DWORD>; #[repr(C)] pub struct CONDITION_VARIABLE { pub ptr: LPVOID } @@ -413,6 +431,12 @@ extern "system" { pub fn SetHandleInformation(hObject: libc::HANDLE, dwMask: libc::DWORD, dwFlags: libc::DWORD) -> libc::BOOL; + pub fn CopyFileExW(lpExistingFileName: libc::LPCWSTR, + lpNewFileName: libc::LPCWSTR, + lpProgressRoutine: LPPROGRESS_ROUTINE, + lpData: libc::LPVOID, + pbCancel: LPBOOL, + dwCopyFlags: libc::DWORD) -> libc::BOOL; } // Functions that aren't available on Windows XP, but we still use them and just diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index 36fabe72aa0..ae6b20de639 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -575,3 +575,28 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> { PathBuf::from(OsString::from_wide(buf)) }) } + +pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { + unsafe extern "system" fn callback( + _TotalFileSize: libc::LARGE_INTEGER, + TotalBytesTransferred: libc::LARGE_INTEGER, + _StreamSize: libc::LARGE_INTEGER, + _StreamBytesTransferred: libc::LARGE_INTEGER, + _dwStreamNumber: libc::DWORD, + _dwCallbackReason: libc::DWORD, + _hSourceFile: HANDLE, + _hDestinationFile: HANDLE, + lpData: libc::LPVOID, + ) -> libc::DWORD { + *(lpData as *mut i64) = TotalBytesTransferred; + c::PROGRESS_CONTINUE + } + let pfrom = to_utf16(from); + let pto = to_utf16(to); + let mut size = 0i64; + try!(cvt(unsafe { + c::CopyFileExW(pfrom.as_ptr(), pto.as_ptr(), Some(callback), + &mut size as *mut _ as *mut _, ptr::null_mut(), 0) + })); + Ok(size as u64) +} |
