Merge pull request #2591 from GoNZooo/g.add-poll-for-unix

feat(os_linux): add `poll` & `ppoll`
This commit is contained in:
Jeroen van Rijn
2023-06-17 08:27:42 +02:00
committed by GitHub
2 changed files with 58 additions and 0 deletions
+24
View File
@@ -432,6 +432,14 @@ 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,
}
sigset_t :: distinct u64
foreign libc {
@(link_name="__errno_location") __errno_location :: proc() -> ^int ---
@@ -1087,3 +1095,19 @@ fcntl :: proc(fd: int, cmd: int, arg: int) -> (int, Errno) {
}
return result, ERROR_NONE
}
poll :: proc(fds: []pollfd, timeout: int) -> (int, Errno) {
result := unix.sys_poll(raw_data(fds), uint(len(fds)), timeout)
if result < 0 {
return 0, _get_errno(result)
}
return result, ERROR_NONE
}
ppoll :: proc(fds: []pollfd, timeout: ^unix.timespec, sigmask: ^sigset_t) -> (int, Errno) {
result := unix.sys_ppoll(raw_data(fds), uint(len(fds)), timeout, sigmask, size_of(sigset_t))
if result < 0 {
return 0, _get_errno(result)
}
return result, ERROR_NONE
}
+34
View File
@@ -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,23 @@ sys_fcntl :: proc "contextless" (fd: int, cmd: int, arg: int) -> int {
return int(intrinsics.syscall(SYS_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg)))
}
sys_poll :: proc "contextless" (fds: rawptr, nfds: uint, timeout: int) -> int {
// NOTE: specialcased here because `arm64` does not have `poll`
when ODIN_ARCH == .arm64 {
seconds := i64(timeout / 1_000)
nanoseconds := i64((timeout % 1000) * 1_000_000)
timeout_spec := timespec{seconds, nanoseconds}
return int(intrinsics.syscall(SYS_ppoll, uintptr(fds), uintptr(nfds), uintptr(&timeout_spec), uintptr(0), uintptr(8)))
} else {
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)