std.os: add timerfd_create, timerfd_settime and timerfd_gettime

This commit is contained in:
Thiago Teodoro Pereira Silva 2022-05-16 19:56:33 -03:00 committed by GitHub
parent 1de7b8d26c
commit 7a4758ed78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 0 deletions

View File

@ -6926,3 +6926,52 @@ pub fn perf_event_open(
else => |err| return unexpectedErrno(err),
}
}
pub const TimerFdCreateError = error{
AccessDenied,
ProcessFdQuotaExceeded,
SystemFdQuotaExceeded,
NoDevice,
SystemResources,
} || UnexpectedError;
pub const TimerFdGetError = error{InvalidHandle} || UnexpectedError;
pub const TimerFdSetError = TimerFdGetError || error{Canceled};
pub fn timerfd_create(clokid: i32, flags: u32) TimerFdCreateError!fd_t {
var rc = linux.timerfd_create(clokid, flags);
return switch (errno(rc)) {
.SUCCESS => @intCast(fd_t, rc),
.INVAL => unreachable,
.MFILE => return error.ProcessFdQuotaExceeded,
.NFILE => return error.SystemFdQuotaExceeded,
.NODEV => return error.NoDevice,
.NOMEM => return error.SystemResources,
.PERM => return error.AccessDenied,
else => |err| return unexpectedErrno(err),
};
}
pub fn timerfd_settime(fd: i32, flags: u32, new_value: *const linux.itimerspec, old_value: ?*linux.itimerspec) TimerFdSetError!void {
var rc = linux.timerfd_settime(fd, flags, new_value, old_value);
return switch (errno(rc)) {
.SUCCESS => {},
.BADF => error.InvalidHandle,
.FAULT => unreachable,
.INVAL => unreachable,
.CANCELED => error.Canceled,
else => |err| return unexpectedErrno(err),
};
}
pub fn timerfd_gettime(fd: i32) TimerFdGetError!linux.itimerspec {
var curr_value: linux.itimerspec = undefined;
var rc = linux.timerfd_gettime(fd, &curr_value);
return switch (errno(rc)) {
.SUCCESS => return curr_value,
.BADF => error.InvalidHandle,
.FAULT => unreachable,
.INVAL => unreachable,
else => |err| return unexpectedErrno(err),
};
}

View File

@ -1000,3 +1000,23 @@ test "access smoke test" {
file_path = try fs.path.join(allocator, &[_][]const u8{ base_path, "some_dir" });
try os.access(file_path, os.F_OK);
}
test "timerfd" {
if (native_os != .linux)
return error.SkipZigTest;
const linux = os.linux;
var tfd = try os.timerfd_create(linux.CLOCK.MONOTONIC, linux.TFD.CLOEXEC);
defer os.close(tfd);
var sit: linux.itimerspec = .{ .it_interval = .{ .tv_sec = 0, .tv_nsec = 0 }, .it_value = .{ .tv_sec = 0, .tv_nsec = 10 * (1000 * 1000) } };
try os.timerfd_settime(tfd, 0, &sit, null);
var fds: [1]os.pollfd = .{.{ .fd = tfd, .events = os.linux.POLL.IN, .revents = 0 }};
try expectEqual(try os.poll(&fds, -1), 1);
var git = try os.timerfd_gettime(tfd);
try expectEqual(git, .{ .it_interval = .{ .tv_sec = 0, .tv_nsec = 0 }, .it_value = .{ .tv_sec = 0, .tv_nsec = 0 } });
try os.timerfd_settime(tfd, 0, &sit, null);
try expectEqual(try os.poll(&fds, 5), 0);
}