From 4f2b9835f5f6966c5f11fe20f9f56855c54e4ce5 Mon Sep 17 00:00:00 2001 From: Rickard Andersson Date: Wed, 14 Jun 2023 22:13:36 +0300 Subject: [PATCH] feat(unix): add `poll` --- core/os/os_linux.odin | 36 +++++++++++++++++++++++++++++++ core/sys/unix/syscalls_linux.odin | 29 +++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 7a0a4b1dd..beb4acec5 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -432,6 +432,18 @@ AT_FDCWD :: ~uintptr(99) /* -100 */ AT_REMOVEDIR :: uintptr(0x200) AT_SYMLINK_NOFOLLOW :: uintptr(0x100) +pollfd :: struct { + fd: c.int, + events: c.short, + revents: c.short, +} + +nfds_t :: distinct c.uint + +sigset_t :: struct { + __val: [16]c.ulong, +} + foreign libc { @(link_name="__errno_location") __errno_location :: proc() -> ^int --- @@ -1087,3 +1099,27 @@ fcntl :: proc(fd: int, cmd: int, arg: int) -> (int, Errno) { } return result, ERROR_NONE } + +// select :: proc(nfds: int, readfds: ^fd_set, writefds: ^fd_set, exceptfds: ^fd_set, timeout: ^timeval) -> (int, Errno) { +// result := unix.sys_select(nfds, readfds, writefds, exceptfds, timeout) +// if result < 0 { +// return 0, _get_errno(result) +// } +// return result, ERROR_NONE +// } + +poll :: proc(fds: [^]pollfd, nfds: nfds_t, timeout: int) -> (int, Errno) { + result := unix.sys_poll(fds, uint(nfds), timeout) + if result < 0 { + return 0, _get_errno(result) + } + return result, ERROR_NONE +} + +ppoll :: proc(fds: [^]pollfd, nfds: nfds_t, timeout: ^unix.timespec, sigmask: ^sigset_t) -> (int, Errno) { + result := unix.sys_ppoll(fds, uint(nfds), timeout, sigmask, size_of(sigset_t)) + if result < 0 { + return 0, _get_errno(result) + } + return result, ERROR_NONE +} diff --git a/core/sys/unix/syscalls_linux.odin b/core/sys/unix/syscalls_linux.odin index abdcf0b92..54f8bcc25 100644 --- a/core/sys/unix/syscalls_linux.odin +++ b/core/sys/unix/syscalls_linux.odin @@ -1567,6 +1567,23 @@ MADV_HWPOISON :: 100 // pipe2 flags O_CLOEXEC :: 0o2000000 +// poll events +POLLIN :: 0x0001 +POLLPRI :: 0x0002 +POLLOUT :: 0x0004 +POLLERR :: 0x0008 +POLLHUP :: 0x0010 +POLLNVAL :: 0x0020 +POLLRDNORM :: 0x0040 +POLLRDBAND :: 0x0080 +POLLWRNORM :: 0x0100 +POLLWRBAND :: 0x0200 +POLLMSG :: 0x0400 +POLLREMOVE :: 0x1000 +POLLRDHUP :: 0x2000 +POLLFREE :: 0x4000 +POLL_BUSY_LOOP :: 0x8000 + // perf event data Perf_Sample :: struct #raw_union { period: u64, @@ -2057,6 +2074,18 @@ sys_fcntl :: proc "contextless" (fd: int, cmd: int, arg: int) -> int { return int(intrinsics.syscall(SYS_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg))) } +sys_select :: proc "contextless" (nfds: int, readfds, writefds, exceptfds: rawptr, timeout: rawptr) -> int { + return int(intrinsics.syscall(SYS_select, uintptr(nfds), uintptr(readfds), uintptr(writefds), uintptr(exceptfds), uintptr(timeout))) +} + +sys_poll :: proc "contextless" (fds: rawptr, nfds: uint, timeout: int) -> int { + return int(intrinsics.syscall(SYS_poll, uintptr(fds), uintptr(nfds), uintptr(timeout))) +} + +sys_ppoll :: proc "contextless" (fds: rawptr, nfds: uint, timeout: rawptr, sigmask: rawptr, sigsetsize: uint) -> int { + return int(intrinsics.syscall(SYS_ppoll, uintptr(fds), uintptr(nfds), uintptr(timeout), uintptr(sigmask), uintptr(sigsetsize))) +} + get_errno :: proc "contextless" (res: int) -> i32 { if res < 0 && res > -4096 { return i32(-res)