Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Made fs::copy return the length of the main stream #44895

Merged
merged 1 commit into from
Oct 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions src/libstd/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1374,14 +1374,17 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
/// Note that if `from` and `to` both point to the same file, then the file
/// will likely get truncated by this operation.
///
/// On success, the total number of bytes copied is returned.
/// On success, the total number of bytes copied is returned and it is equal to
/// the length of the `to` file as reported by `metadata`.
///
/// # Platform-specific behavior
///
/// This function currently corresponds to the `open` function in Unix
/// with `O_RDONLY` for `from` and `O_WRONLY`, `O_CREAT`, and `O_TRUNC` for `to`.
/// `O_CLOEXEC` is set for returned file descriptors.
/// On Windows, this function currently corresponds to `CopyFileEx`.
/// On Windows, this function currently corresponds to `CopyFileEx`. Alternate
/// NTFS streams are copied but only the size of the main stream is returned by
/// this function.
/// Note that, this [may change in the future][changes].
///
/// [changes]: ../io/index.html#platform-specific-behavior
Expand Down Expand Up @@ -2589,13 +2592,25 @@ mod tests {
fn copy_file_preserves_streams() {
let tmp = tmpdir();
check!(check!(File::create(tmp.join("in.txt:bunny"))).write("carrot".as_bytes()));
assert_eq!(check!(fs::copy(tmp.join("in.txt"), tmp.join("out.txt"))), 6);
assert_eq!(check!(fs::copy(tmp.join("in.txt"), tmp.join("out.txt"))), 0);
assert_eq!(check!(tmp.join("out.txt").metadata()).len(), 0);
let mut v = Vec::new();
check!(check!(File::open(tmp.join("out.txt:bunny"))).read_to_end(&mut v));
assert_eq!(v, b"carrot".to_vec());
}

#[test]
fn copy_file_returns_metadata_len() {
let tmp = tmpdir();
let in_path = tmp.join("in.txt");
let out_path = tmp.join("out.txt");
check!(check!(File::create(&in_path)).write(b"lettuce"));
#[cfg(windows)]
check!(check!(File::create(tmp.join("in.txt:bunny"))).write(b"carrot"));
let copied_len = check!(fs::copy(&in_path, &out_path));
assert_eq!(check!(out_path.metadata()).len(), copied_len);
}

#[test]
fn symlinks_work() {
let tmpdir = tmpdir();
Expand Down
8 changes: 4 additions & 4 deletions src/libstd/sys/windows/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,16 +722,16 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
unsafe extern "system" fn callback(
_TotalFileSize: c::LARGE_INTEGER,
TotalBytesTransferred: c::LARGE_INTEGER,
_TotalBytesTransferred: c::LARGE_INTEGER,
_StreamSize: c::LARGE_INTEGER,
_StreamBytesTransferred: c::LARGE_INTEGER,
_dwStreamNumber: c::DWORD,
StreamBytesTransferred: c::LARGE_INTEGER,
dwStreamNumber: c::DWORD,
_dwCallbackReason: c::DWORD,
_hSourceFile: c::HANDLE,
_hDestinationFile: c::HANDLE,
lpData: c::LPVOID,
) -> c::DWORD {
*(lpData as *mut i64) = TotalBytesTransferred;
if dwStreamNumber == 1 {*(lpData as *mut i64) = StreamBytesTransferred;}
c::PROGRESS_CONTINUE
}
let pfrom = to_u16s(from)?;
Expand Down