From 797a4574d1a733d4e3186a40d3e77dc0ab8c1278 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 29 Nov 2023 09:14:13 -0800 Subject: [PATCH] Implement `pause`. (#948) --- src/backend/libc/event/syscalls.rs | 8 +++++++ src/backend/linux_raw/event/syscalls.rs | 21 ++++++++++++++++- src/event/mod.rs | 4 ++++ src/event/pause.rs | 31 +++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 src/event/pause.rs diff --git a/src/backend/libc/event/syscalls.rs b/src/backend/libc/event/syscalls.rs index f2dcdf5ad..725ec8250 100644 --- a/src/backend/libc/event/syscalls.rs +++ b/src/backend/libc/event/syscalls.rs @@ -181,3 +181,11 @@ pub(crate) fn port_send( ) -> io::Result<()> { unsafe { ret(c::port_send(borrowed_fd(port), events, userdata)) } } + +#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +pub(crate) fn pause() { + let r = unsafe { libc::pause() }; + let errno = libc_errno::errno().0; + debug_assert_eq!(r, -1); + debug_assert_eq!(errno, libc::EINTR); +} diff --git a/src/backend/linux_raw/event/syscalls.rs b/src/backend/linux_raw/event/syscalls.rs index 6cb8d3d96..0ae775339 100644 --- a/src/backend/linux_raw/event/syscalls.rs +++ b/src/backend/linux_raw/event/syscalls.rs @@ -9,7 +9,7 @@ use crate::backend::c; #[cfg(feature = "alloc")] use crate::backend::conv::pass_usize; use crate::backend::conv::{ - by_ref, c_int, c_uint, raw_fd, ret, ret_owned_fd, ret_usize, slice_mut, zero, + by_ref, c_int, c_uint, raw_fd, ret, ret_error, ret_owned_fd, ret_usize, slice_mut, zero, }; use crate::event::{epoll, EventfdFlags, PollFd}; use crate::fd::{BorrowedFd, OwnedFd}; @@ -131,3 +131,22 @@ pub(crate) fn epoll_wait( pub(crate) fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result { unsafe { ret_owned_fd(syscall_readonly!(__NR_eventfd2, c_uint(initval), flags)) } } + +#[inline] +pub(crate) fn pause() { + unsafe { + #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] + let error = ret_error(syscall_readonly!( + __NR_ppoll, + zero(), + zero(), + zero(), + zero() + )); + + #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] + let error = ret_error(syscall_readonly!(__NR_pause)); + + debug_assert_eq!(error, io::Errno::INTR); + } +} diff --git a/src/event/mod.rs b/src/event/mod.rs index b0b62e0a6..b6b7f9971 100644 --- a/src/event/mod.rs +++ b/src/event/mod.rs @@ -9,6 +9,8 @@ mod eventfd; #[cfg(all(feature = "alloc", bsd))] pub mod kqueue; +#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +mod pause; mod poll; #[cfg(solarish)] pub mod port; @@ -22,4 +24,6 @@ pub use crate::backend::event::epoll; target_os = "espidf" ))] pub use eventfd::{eventfd, EventfdFlags}; +#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +pub use pause::*; pub use poll::{poll, PollFd, PollFlags}; diff --git a/src/event/pause.rs b/src/event/pause.rs new file mode 100644 index 000000000..f19108490 --- /dev/null +++ b/src/event/pause.rs @@ -0,0 +1,31 @@ +use crate::backend; + +/// `pause()` +/// +/// The POSIX `pause` interface returns an error code, but the only thing +/// `pause` does is sleep until interrupted by a signal, so it always +/// returns the same thing with the same error code, so in rustix, the +/// return value is omitted. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// - [Apple] +/// - [FreeBSD] +/// - [NetBSD] +/// - [OpenBSD] +/// - [DragonFly BSD] +/// - [illumos] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pause.html +/// [Linux]: https://man7.org/linux/man-pages/man2/pause.2.html +/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/pause.3.html +/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=pause&sektion=3 +/// [NetBSD]: https://man.netbsd.org/pause.3 +/// [OpenBSD]: https://man.openbsd.org/pause.3 +/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=pause§ion=3 +/// [illumos]: https://illumos.org/man/2/pause +#[inline] +pub fn pause() { + backend::event::syscalls::pause() +}