zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit c71e8a30cdf050e45c2ca2dc81e93b10cf00dc5f (tree)
parent 7f32c799a95dd8a54ca7f984f41524021ceee2ce
Author: Vincent Rischmann <vincent@rischmann.fr>
Date:   Sat, 27 Feb 2021 23:30:43 +0100

os/linux: add fadvise

Diffstat:
Mlib/std/os/linux.zig | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mlib/std/os/linux/test.zig | 20++++++++++++++++++++
2 files changed, 79 insertions(+), 0 deletions(-)

diff --git 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 @@ -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); +}