aboutsummaryrefslogtreecommitdiff
path: root/lib/std/fs
diff options
context:
space:
mode:
authorMaciej Walczak <14938807+xackus@users.noreply.github.com>2020-08-11 21:49:43 +0200
committerGitHub <noreply@github.com>2020-08-11 15:49:43 -0400
commit6febe7e977072fea1bf7b6003be2d6c1f3654905 (patch)
tree77c7d9bae1ec5ea2e7254eefba240f50f6904390 /lib/std/fs
parent2b28cebf644b29543fcb52504b11931a7c797ffb (diff)
downloadzig-6febe7e977072fea1bf7b6003be2d6c1f3654905.tar.gz
zig-6febe7e977072fea1bf7b6003be2d6c1f3654905.zip
copy_file_range linux syscall (#6010)
Diffstat (limited to 'lib/std/fs')
-rw-r--r--lib/std/fs/file.zig9
-rw-r--r--lib/std/fs/test.zig26
2 files changed, 28 insertions, 7 deletions
diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig
index 3b79e4e01b..ce71571c9f 100644
--- a/lib/std/fs/file.zig
+++ b/lib/std/fs/file.zig
@@ -607,15 +607,10 @@ pub const File = struct {
}
}
- pub const CopyRangeError = PWriteError || PReadError;
+ pub const CopyRangeError = os.CopyFileRangeError;
pub fn copyRange(in: File, in_offset: u64, out: File, out_offset: u64, len: usize) CopyRangeError!usize {
- // TODO take advantage of copy_file_range OS APIs
- var buf: [8 * 4096]u8 = undefined;
- const adjusted_count = math.min(buf.len, len);
- const amt_read = try in.pread(buf[0..adjusted_count], in_offset);
- if (amt_read == 0) return @as(usize, 0);
- return out.pwrite(buf[0..amt_read], out_offset);
+ return os.copy_file_range(in.handle, in_offset, out.handle, out_offset, len, 0);
}
/// Returns the number of bytes copied. If the number read is smaller than `buffer.len`, it
diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig
index c9f1711967..26d8632c37 100644
--- a/lib/std/fs/test.zig
+++ b/lib/std/fs/test.zig
@@ -328,6 +328,32 @@ test "sendfile" {
testing.expect(mem.eql(u8, written_buf[0..amt], "header1\nsecond header\nine1\nsecontrailer1\nsecond trailer\n"));
}
+test "copyRangeAll" {
+ var tmp = tmpDir(.{});
+ defer tmp.cleanup();
+
+ try tmp.dir.makePath("os_test_tmp");
+ defer tmp.dir.deleteTree("os_test_tmp") catch {};
+
+ var dir = try tmp.dir.openDir("os_test_tmp", .{});
+ defer dir.close();
+
+ var src_file = try dir.createFile("file1.txt", .{ .read = true });
+ defer src_file.close();
+
+ const data = "u6wj+JmdF3qHsFPE BUlH2g4gJCmEz0PP";
+ try src_file.writeAll(data);
+
+ var dest_file = try dir.createFile("file2.txt", .{ .read = true });
+ defer dest_file.close();
+
+ var written_buf: [100]u8 = undefined;
+ _ = try src_file.copyRangeAll(0, dest_file, 0, data.len);
+
+ const amt = try dest_file.preadAll(&written_buf, 0);
+ testing.expect(mem.eql(u8, written_buf[0..amt], data));
+}
+
test "fs.copyFile" {
const data = "u6wj+JmdF3qHsFPE BUlH2g4gJCmEz0PP";
const src_file = "tmp_test_copy_file.txt";