Skip to content

Commit 497bd4b

Browse files
committed
Use libc::syscall instead of libc::copy_file_range
It seems that many Linux distros don't include copy_file_range in their C libraries.
1 parent 0b4afa7 commit 497bd4b

File tree

1 file changed

+28
-10
lines changed

1 file changed

+28
-10
lines changed

src/fcntl.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -645,16 +645,34 @@ pub fn copy_file_range<Fd1: AsFd, Fd2: AsFd>(
645645
.map(|offset| offset as *mut type_of_off)
646646
.unwrap_or(ptr::null_mut());
647647

648-
let ret = unsafe {
649-
libc::copy_file_range(
650-
fd_in.as_fd().as_raw_fd(),
651-
off_in,
652-
fd_out.as_fd().as_raw_fd(),
653-
off_out,
654-
len,
655-
0,
656-
)
657-
};
648+
cfg_if::cfg_if! {
649+
if #[cfg(target_os = "freebsd")] {
650+
let ret = unsafe {
651+
libc::copy_file_range(
652+
fd_in.as_fd().as_raw_fd(),
653+
off_in,
654+
fd_out.as_fd().as_raw_fd(),
655+
off_out,
656+
len,
657+
0,
658+
)
659+
};
660+
} else {
661+
// May Linux distros still don't include copy_file_range in their
662+
// libc implementations, so we need to make a direct syscall.
663+
let ret = unsafe {
664+
libc::syscall(
665+
libc::SYS_copy_file_range,
666+
fd_in,
667+
off_in,
668+
fd_out.as_fd().as_raw_fd(),
669+
off_out,
670+
len,
671+
0,
672+
)
673+
};
674+
}
675+
}
658676
Errno::result(ret).map(|r| r as usize)
659677
}
660678

0 commit comments

Comments
 (0)