copy_file_range(2) System Calls Manual copy_file_range(2) copy_file_range - C (libc, -lc) #define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include ssize_t copy_file_range(int fd_in, off_t *_Nullable off_in, int fd_out, off_t *_Nullable off_out, size_t len, unsigned int flags); copy_file_range() . len fd_in fd_out , . off_in off_out: o off_in NULL, fd_in , . o off_in NULL, off_in , fd_in, . fd_in , off_in . fd_in fd_out . , . flags , 0. copy_file_range() . . fd_in , copy_file_range() . copy_file_range() -1, errno . EBADF . EBADF fd_in fd_out . EBADF , fd_out, O_APPEND ( open(2)). EFBIG . EFBIG , . . EFBIG , . SIGXFSZ. EINVAL flags 0. EINVAL fd_in fd_out . EINVAL fd_in fd_out . EIO -. EISDIR fd_in fd_out . ENOMEM . ENOSPC . EOPNOTSUPP ( Linux 5.19) . EOVERFLOW . EPERM fd_out (immutable). ETXTBSY fd_in fd_out . EXDEV ( Linux 5.3) The files referred to by fd_in and fd_out are not on the same filesystem. EXDEV ( Linux 5.19) The files referred to by fd_in and fd_out are not on the same filesystem, and the source and target filesystems are not of the same type, or do not support cross-filesystem copy. A major rework of the kernel implementation occurred in Linux 5.3. Areas of the API that weren't clearly defined were clarified and the API bounds are much more strictly checked than on earlier kernels. Since Linux 5.19, cross-filesystem copies can be achieved when both filesystems are of the same type, and that filesystem implements support for it. See BUGS for behavior prior to Linux 5.19. Linux 5.19, . Linux, GNU. Linux 4.5, but glibc 2.27 provides a user-space emulation when it is not available. fd_in (sparse), copy_file_range() , . copy_file_range() , lseek(2) SEEK_DATA SEEK_HOLE . copy_file_range() << >>, , (. ., , -- ) -- (server-side-copy, NFS). _FILE_OFFSET_BITS should be defined to be 64 in code that uses non-null off_in or off_out or that takes the address of copy_file_range, if the code is intended to be portable to traditional 32-bit x86 and ARM platforms where off_t's width defaults to 32 bits. In Linux 5.3 to Linux 5.18, cross-filesystem copies were implemented by the kernel, if the operation was not supported by individual filesystems. However, on some virtual filesystems, the call failed to copy, while still reporting success. #define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include #include #include #include #include #include int main(int argc, char *argv[]) { int fd_in, fd_out; off_t len, ret; struct stat stat; if (argc != 3) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(EXIT_FAILURE); } fd_in = open(argv[1], O_RDONLY); if (fd_in == -1) { perror("open (argv[1])"); exit(EXIT_FAILURE); } if (fstat(fd_in, &stat) == -1) { perror("fstat"); exit(EXIT_FAILURE); } len = stat.st_size; fd_out = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0644); if (fd_out == -1) { perror("open (argv[2])"); exit(EXIT_FAILURE); } do { ret = copy_file_range(fd_in, NULL, fd_out, NULL, len, 0); if (ret == -1) { perror("copy_file_range"); exit(EXIT_FAILURE); } len -= ret; } while (len > 0 && ret > 0); close(fd_in); close(fd_out); exit(EXIT_SUCCESS); } lseek(2), sendfile(2), splice(2) () Azamat Hackimov , Dmitriy S. Seregin , Dmitry Bolkhovskikh , Katrin Kutepova , Yuri Kozlov , Kirill Rekhov ; GNU (GNU General Public License - GPL, 3 ) , - . - , , () () () <>. Linux 6.9.1 15 2024 . copy_file_range(2)