diff --git a/lib/std/c.zig b/lib/std/c.zig index d8cb14e1a2..f461b2e9ce 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -295,6 +295,7 @@ pub extern "c" fn getnameinfo( pub extern "c" fn gai_strerror(errcode: EAI) [*:0]const u8; pub extern "c" fn poll(fds: [*]pollfd, nfds: nfds_t, timeout: c_int) c_int; +pub extern "c" fn ppoll(fds: [*]pollfd, nfds: nfds_t, timeout: ?*const timespec, sigmask: ?*const sigset_t) c_int; pub extern "c" fn dn_expand( msg: [*:0]const u8, diff --git a/lib/std/os.zig b/lib/std/os.zig index d8385e9770..2a6c8b2a52 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -2298,7 +2298,7 @@ pub const ChangeCurDirError = error{ SystemResources, NotDir, BadPathName, - + /// On Windows, file paths must be valid Unicode. InvalidUtf8, } || UnexpectedError; @@ -5250,6 +5250,32 @@ pub fn poll(fds: []pollfd, timeout: i32) PollError!usize { } } +pub const PPollError = error{ + /// The operation was interrupted by a delivery of a signal before it could complete. + SignalInterrupt, + + /// The kernel had no space to allocate file descriptor tables. + SystemResources, +} || UnexpectedError; + +pub fn ppoll(fds: []pollfd, timeout: ?*const timespec, mask: ?*const sigset_t) PPollError!usize { + var ts: timespec = undefined; + var ts_ptr: ?*timespec = null; + if (timeout) |timeout_ns| { + ts_ptr = &ts; + ts = timeout_ns.*; + } + const rc = system.ppoll(fds.ptr, fds.len, ts_ptr, mask); + switch (errno(rc)) { + 0 => return @intCast(usize, rc), + EFAULT => unreachable, + EINTR => return error.SignalInterrupt, + EINVAL => unreachable, + ENOMEM => return error.SystemResources, + else => |err| return unexpectedErrno(err), + } +} + pub const RecvFromError = error{ /// The socket is marked nonblocking and the requested operation would block, and /// there is no global event loop configured. @@ -5565,7 +5591,7 @@ pub fn signalfd(fd: fd_t, mask: *const sigset_t, flags: u32) !fd_t { EMFILE => return error.ProcessResources, ENODEV => return error.InodeMountFail, ENOSYS => return error.SystemOutdated, - else => |err| return std.os.unexpectedErrno(err), + else => |err| return unexpectedErrno(err), } } @@ -5590,7 +5616,7 @@ pub fn syncfs(fd: fd_t) SyncError!void { EIO => return error.InputOutput, ENOSPC => return error.NoSpaceLeft, EDQUOT => return error.DiskQuota, - else => |err| return std.os.unexpectedErrno(err), + else => |err| return unexpectedErrno(err), } } @@ -5614,7 +5640,7 @@ pub fn fsync(fd: fd_t) SyncError!void { EIO => return error.InputOutput, ENOSPC => return error.NoSpaceLeft, EDQUOT => return error.DiskQuota, - else => |err| return std.os.unexpectedErrno(err), + else => |err| return unexpectedErrno(err), } } @@ -5633,7 +5659,7 @@ pub fn fdatasync(fd: fd_t) SyncError!void { EIO => return error.InputOutput, ENOSPC => return error.NoSpaceLeft, EDQUOT => return error.DiskQuota, - else => |err| return std.os.unexpectedErrno(err), + else => |err| return unexpectedErrno(err), } } @@ -5675,7 +5701,7 @@ pub fn prctl(option: PR, args: anytype) PrctlError!u31 { EOPNOTSUPP => return error.OperationNotSupported, EPERM, EBUSY => return error.PermissionDenied, ERANGE => unreachable, - else => |err| return std.os.unexpectedErrno(err), + else => |err| return unexpectedErrno(err), } } @@ -5688,7 +5714,7 @@ pub fn getrlimit(resource: rlimit_resource) GetrlimitError!rlimit { 0 => return limits, EFAULT => unreachable, // bogus pointer EINVAL => unreachable, - else => |err| return std.os.unexpectedErrno(err), + else => |err| return unexpectedErrno(err), } } @@ -5701,6 +5727,6 @@ pub fn setrlimit(resource: rlimit_resource, limits: rlimit) SetrlimitError!void EFAULT => unreachable, // bogus pointer EINVAL => unreachable, EPERM => return error.PermissionDenied, - else => |err| return std.os.unexpectedErrno(err), + else => |err| return unexpectedErrno(err), } } diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 5299c995a0..56e9d45a08 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -278,7 +278,7 @@ pub fn poll(fds: [*]pollfd, n: nfds_t, timeout: i32) usize { if (@hasField(SYS, "poll")) { return syscall3(.poll, @ptrToInt(fds), n, @bitCast(u32, timeout)); } else { - return syscall6( + return syscall5( .ppoll, @ptrToInt(fds), n, @@ -290,12 +290,15 @@ pub fn poll(fds: [*]pollfd, n: nfds_t, timeout: i32) usize { else null), 0, - 0, NSIG / 8, ); } } +pub fn ppoll(fds: [*]pollfd, n: nfds_t, timeout: ?*timespec, sigmask: ?*const sigset_t) usize { + return syscall5(.ppoll, @ptrToInt(fds), n, @ptrToInt(timeout), @ptrToInt(sigmask), NSIG / 8); +} + pub fn read(fd: i32, buf: [*]u8, count: usize) usize { return syscall3(.read, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count); } @@ -1194,7 +1197,7 @@ pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout return epoll_pwait(epoll_fd, events, maxevents, timeout, null); } -pub fn epoll_pwait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32, sigmask: ?*sigset_t) usize { +pub fn epoll_pwait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32, sigmask: ?*const sigset_t) usize { return syscall6( .epoll_pwait, @bitCast(usize, @as(isize, epoll_fd)),