### 13.7 Copying data between two files ¶

A special function is provided to copy data between two files on the same file system. The system can optimize such copy operations. This is particularly important on network file systems, where the data would otherwise have to be transferred twice over the network.

Note that this function only copies file data, but not metadata such as file permissions or extended attributes.

Function: `ssize_t` copy_file_range `(int inputfd, off64_t *inputpos, int outputfd, off64_t *outputpos, ssize_t length, unsigned int flags)` ¶

  Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.

  This function copies up to length bytes from the file descriptor inputfd to the file descriptor outputfd.

  The function can operate on both the current file position (like `read` and `write`) and an explicit offset (like `pread` and `pwrite`). If the inputpos pointer is null, the file position of inputfd is used as the starting point of the copy operation, and the file position is advanced during it. If inputpos is not null, then `*inputpos` is used as the starting point of the copy operation, and `*inputpos` is incremented by the number of copied bytes, but the file position remains unchanged. Similar rules apply to outputfd and outputpos for the output file position.

  The flags argument is currently reserved and must be zero.

  The `copy_file_range` function returns the number of bytes copied. This can be less than the specified length in case the input file contains fewer remaining bytes than length, or if a read or write failure occurs. The return value is zero if the end of the input file is encountered immediately.

  If no bytes can be copied, to report an error, `copy_file_range` returns the value -1 and sets `errno`. The table below lists some of the error conditions for this function.

  `ENOSYS`

    The kernel does not implement the required functionality.

  `EISDIR`

    At least one of the descriptors inputfd or outputfd refers to a directory.

  `EINVAL`

    At least one of the descriptors inputfd or outputfd refers to a non-regular, non-directory file (such as a socket or a FIFO).

    The input or output positions before are after the copy operations are outside of an implementation-defined limit.

    The flags argument is not zero.

  `EFBIG`

    The new file size would exceed the process file size limit. See Limiting Resource Usage.

    The input or output positions before are after the copy operations are outside of an implementation-defined limit. This can happen if the file was not opened with large file support (LFS) on 32-bit machines, and the copy operation would create a file which is larger than what `off_t` could represent.

  `EBADF`

    The argument inputfd is not a valid file descriptor open for reading.

    The argument outputfd is not a valid file descriptor open for writing, or outputfd has been opened with `O_APPEND`.

  In addition, `copy_file_range` can fail with the error codes which are used by `read`, `pread`, `write`, and `pwrite`.

  The `copy_file_range` function is a cancellation point. In case of cancellation, the input location (the file position or the value at `*inputpos`) is indeterminate.