aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorVincent Rischmann <vincent@rischmann.fr>2021-02-27 23:30:43 +0100
committerVeikka Tuominen <git@vexu.eu>2021-06-09 18:15:50 +0300
commitc71e8a30cdf050e45c2ca2dc81e93b10cf00dc5f (patch)
tree3641124b53b25db7d628b28d47b423cabb35488b /lib/std
parent7f32c799a95dd8a54ca7f984f41524021ceee2ce (diff)
downloadzig-c71e8a30cdf050e45c2ca2dc81e93b10cf00dc5f.tar.gz
zig-c71e8a30cdf050e45c2ca2dc81e93b10cf00dc5f.zip
os/linux: add fadvise
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/os/linux.zig59
-rw-r--r--lib/std/os/linux/test.zig20
2 files changed, 79 insertions, 0 deletions
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig
index 9e7b38fe90..85916004d1 100644
--- a/lib/std/os/linux.zig
+++ b/lib/std/os/linux.zig
@@ -1454,6 +1454,65 @@ pub fn process_vm_writev(pid: pid_t, local: [*]const iovec, local_count: usize,
);
}
+pub fn fadvise(fd: fd_t, offset: i64, len: i64, advice: usize) usize {
+ if (comptime std.Target.current.cpu.arch.isMIPS()) {
+ // MIPS requires a 7 argument syscall
+
+ const offset_halves = splitValue64(offset);
+ const length_halves = splitValue64(len);
+
+ return syscall7(
+ .fadvise64,
+ @bitCast(usize, @as(isize, fd)),
+ 0,
+ offset_halves[0],
+ offset_halves[1],
+ length_halves[0],
+ length_halves[1],
+ advice,
+ );
+ } else if (comptime std.Target.current.cpu.arch.isARM()) {
+ // ARM reorders the arguments
+
+ const offset_halves = splitValue64(offset);
+ const length_halves = splitValue64(len);
+
+ return syscall6(
+ .fadvise64_64,
+ @bitCast(usize, @as(isize, fd)),
+ advice,
+ offset_halves[0],
+ offset_halves[1],
+ length_halves[0],
+ length_halves[1],
+ );
+ } else if (@hasField(SYS, "fadvise64_64") and usize_bits != 64) {
+ // The extra usize check is needed to avoid SPARC64 because it provides both
+ // fadvise64 and fadvise64_64 but the latter behaves differently than other platforms.
+
+ const offset_halves = splitValue64(offset);
+ const length_halves = splitValue64(len);
+
+ return syscall6(
+ .fadvise64_64,
+ @bitCast(usize, @as(isize, fd)),
+ offset_halves[0],
+ offset_halves[1],
+ length_halves[0],
+ length_halves[1],
+ advice,
+ );
+ } else {
+ return syscall4(
+ .fadvise64,
+ @bitCast(usize, @as(isize, fd)),
+ @bitCast(usize, offset),
+ @bitCast(usize, len),
+ advice,
+ );
+ }
+}
+
test {
if (std.Target.current.os.tag == .linux) {
_ = @import("linux/test.zig");
diff --git a/lib/std/os/linux/test.zig b/lib/std/os/linux/test.zig
index c4a00c48ec..2e98fe359d 100644
--- a/lib/std/os/linux/test.zig
+++ b/lib/std/os/linux/test.zig
@@ -108,3 +108,23 @@ test "user and group ids" {
try expectEqual(linux.getauxval(elf.AT_EUID), linux.geteuid());
try expectEqual(linux.getauxval(elf.AT_EGID), linux.getegid());
}
+
+test "fadvise" {
+ const tmp_file_name = "temp_posix_fadvise.txt";
+ var file = try fs.cwd().createFile(tmp_file_name, .{});
+ defer {
+ file.close();
+ fs.cwd().deleteFile(tmp_file_name) catch {};
+ }
+
+ var buf: [2048]u8 = undefined;
+ try file.writeAll(&buf);
+
+ const ret = linux.fadvise(
+ file.handle,
+ 0,
+ 0,
+ linux.POSIX_FADV_SEQUENTIAL,
+ );
+ try expectEqual(@as(usize, 0), ret);
+}