about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-06-02 03:06:26 +0000
committerbors <bors@rust-lang.org>2018-06-02 03:06:26 +0000
commitedae1cc38b467518a8eea590c9c3e0c103b4ecb0 (patch)
tree5b4cb2046c82c1999db04f97e225e7c9f4ba22ed
parent5f7c9da0a774cdc4a4768a3873521286b632224b (diff)
parent2c3eff99f0cc0bb460f9068c553e5d029e7b7ec3 (diff)
downloadrust-edae1cc38b467518a8eea590c9c3e0c103b4ecb0.tar.gz
rust-edae1cc38b467518a8eea590c9c3e0c103b4ecb0.zip
Auto merge of #51270 - nicokoch:issue-51266, r=TimNN
fs: copy: Add EPERM to fallback error conditions

Fixes #51266
-rw-r--r--src/libstd/sys/unix/fs.rs17
1 files changed, 12 insertions, 5 deletions
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index c4092dcd388..774340388e1 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -890,8 +890,11 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
                     )
             };
             if let Err(ref copy_err) = copy_result {
-                if let Some(libc::ENOSYS) = copy_err.raw_os_error() {
-                    HAS_COPY_FILE_RANGE.store(false, Ordering::Relaxed);
+                match copy_err.raw_os_error() {
+                    Some(libc::ENOSYS) | Some(libc::EPERM) => {
+                        HAS_COPY_FILE_RANGE.store(false, Ordering::Relaxed);
+                    }
+                    _ => {}
                 }
             }
             copy_result
@@ -902,9 +905,13 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
             Ok(ret) => written += ret as u64,
             Err(err) => {
                 match err.raw_os_error() {
-                    Some(os_err) if os_err == libc::ENOSYS || os_err == libc::EXDEV => {
-                        // Either kernel is too old or the files are not mounted on the same fs.
-                        // Try again with fallback method
+                    Some(os_err) if os_err == libc::ENOSYS
+                                 || os_err == libc::EXDEV
+                                 || os_err == libc::EPERM => {
+                        // Try fallback io::copy if either:
+                        // - Kernel version is < 4.5 (ENOSYS)
+                        // - Files are mounted on different fs (EXDEV)
+                        // - copy_file_range is disallowed, for example by seccomp (EPERM)
                         assert_eq!(written, 0);
                         let ret = io::copy(&mut reader, &mut writer)?;
                         writer.set_permissions(perm)?;