# os.copy_file_range: save a syscall for most operations · gitcafe/zig

[View on GitCafe](https://git.cafe/gitcafe/zig/commit/fd10baf748aeb3b6d2394701d735098e64638a22)

Repository: [gitcafe/zig](https://git.cafe/gitcafe/zig)

Visibility: public

Requested revision: fd10baf748aeb3b6d2394701d735098e64638a22

Requested commit: fd10baf748aeb3b6d2394701d735098e64638a22

Commit: fd10baf748aeb3b6d2394701d735098e64638a22

Tree: cf68a2365532f691b47a4e8171747474db983ef8

Author: Motiejus Jakštys

Committer: Andrew Kelley

## Message

```
os.copy_file_range: save a syscall for most operations

Currenty copy_file_range always uses at least two syscalls:

1. As many as it needs to do the initial copy (always 1 during my
   testing)
2. The last one is always when offset is the size of the file.

The second syscall is used to detect the terminating condition. However,
because we do a stat for other reasons, we know the size of the file,
and we can skip the syscall.

Sparse files: since copy_file_range expands holes of sparse files, I
conclude that this layer was not intended to work with sparse files. In
other words, this commit does not make it worse for sparse file society.

Test program
------------

    const std = @import("std");

    pub fn main() !void {
        const arg1 = std.mem.span(std.os.argv[1]);
        const arg2 = std.mem.span(std.os.argv[2]);
        try std.fs.cwd().copyFile(arg1, std.fs.cwd(), arg2, .{});
    }

Test output (current master)
----------------------------

Observe two `copy_file_range` syscalls: one with 209 bytes, one with
zero:

    $ zig build-exe cp.zig
    $ strace ./cp ./cp.zig ./cp2.zig |& grep copy_file_range
    copy_file_range(3, [0], 5, [0], 4294967295, 0) = 209
    copy_file_range(3, [209], 5, [209], 4294967295, 0) = 0
    $

Test output (this diff)
-----------------------

Observe a single `copy_file_range` syscall with 209 bytes:

    $ /code/zig/build/zig build-exe cp.zig
    $ strace ./cp ./cp.zig ./cp2.zig |& grep copy_file_range
    copy_file_range(3, [0], 5, [0], 4294967295, 0) = 209
    $

```

## Parents

- [5ec76cf5c84f3863618e220ce41d09cc9781af8a](https://git.cafe/gitcafe/zig/commit/5ec76cf5c84f3863618e220ce41d09cc9781af8a?format=markdown)

[Source at this commit](https://git.cafe/gitcafe/zig/tree/fd10baf748aeb3b6d2394701d735098e64638a22?format=markdown)
