diff --git a/src/uu/cp/src/platform/linux.rs b/src/uu/cp/src/platform/linux.rs index 637b8969c4..302ccbfe6f 100644 --- a/src/uu/cp/src/platform/linux.rs +++ b/src/uu/cp/src/platform/linux.rs @@ -141,6 +141,8 @@ where } let src_fd = src_file.as_raw_fd(); let mut current_offset: isize = 0; + let step = std::cmp::min(size, 16 * 1024 * 1024) as usize; // 16 MiB + let mut buf: Vec = vec![0x0; step]; loop { let result = unsafe { libc::lseek(src_fd, current_offset.try_into().unwrap(), SEEK_DATA) } .try_into() @@ -158,16 +160,12 @@ where return Err(std::io::Error::last_os_error()); } let len: isize = hole - current_offset; - let mut buf: Vec = vec![0x0; len as usize]; - src_file.read_exact_at(&mut buf, current_offset as u64)?; - unsafe { - libc::pwrite( - dst_fd, - buf.as_ptr() as *const libc::c_void, - len as usize, - current_offset.try_into().unwrap(), - ) - }; + for i in (0..len).step_by(step) { + let read_len = std::cmp::min((len - i) as usize, step); + let buf = &mut buf[..read_len]; + src_file.read_exact_at(buf, (current_offset + i) as u64)?; + dst_file.write_all_at(buf, (current_offset + i) as u64)?; + } current_offset = hole; } Ok(()) @@ -198,14 +196,7 @@ where while current_offset < size { let this_read = src_file.read(&mut buf)?; if buf.iter().any(|&x| x != 0) { - unsafe { - libc::pwrite( - dst_fd, - buf.as_ptr() as *const libc::c_void, - this_read, - current_offset.try_into().unwrap(), - ) - }; + dst_file.write_all_at(&buf, current_offset.try_into().unwrap())?; } current_offset += this_read; }