diff --git a/src/header/bits_eventfd/mod.rs b/src/header/bits_eventfd/mod.rs new file mode 100644 index 0000000000..87c8d941fb --- /dev/null +++ b/src/header/bits_eventfd/mod.rs @@ -0,0 +1,4 @@ +//! `bits/eventfd.h` — eventfd counter type. + +use crate::platform::types::uint64_t; +pub type eventfd_t = uint64_t; diff --git a/src/header/mod.rs b/src/header/mod.rs index 6e65c4b23e..c078fbe1c8 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -5,6 +5,7 @@ pub mod _fenv; pub mod arpa_inet; pub mod assert; pub mod bits_arpainet; +pub mod bits_eventfd; pub mod bits_iovec; #[path = "bits_locale-t/mod.rs"] pub mod bits_locale_t; diff --git a/src/header/mod.rs.orig b/src/header/mod.rs.orig new file mode 100644 index 0000000000..c078fbe1c8 --- /dev/null +++ b/src/header/mod.rs.orig @@ -0,0 +1,150 @@ +//! POSIX header implementations. + +pub mod _aio; +pub mod _fenv; +pub mod arpa_inet; +pub mod assert; +pub mod bits_arpainet; +pub mod bits_eventfd; +pub mod bits_iovec; +#[path = "bits_locale-t/mod.rs"] +pub mod bits_locale_t; +pub mod bits_pthread; +#[path = "bits_safamily-t/mod.rs"] +pub mod bits_safamily_t; +#[path = "bits_sigset-t/mod.rs"] +pub mod bits_sigset_t; +#[path = "bits_socklen-t/mod.rs"] +pub mod bits_socklen_t; +pub mod bits_timespec; +// complex.h implemented in C +pub mod cpio; +pub mod crypt; +pub mod ctype; +// TODO: curses.h (deprecated) +// TODO: devctl.h +pub mod dirent; +#[path = "dl-tls/mod.rs"] +pub mod dl_tls; +pub mod dlfcn; +pub mod elf; +pub mod endian; +pub mod err; +pub mod errno; +pub mod fcntl; +pub mod float; +// TODO: fmtmsg.h +pub mod fnmatch; +// TODO: ftw.h +pub mod getopt; +pub mod glob; +pub mod grp; +// TODO: iconv.h +pub mod ifaddrs; +pub mod inttypes; +// iso646.h implemented in C +pub mod langinfo; +// TODO: libintl.h +pub mod libgen; +pub mod limits; +pub mod locale; +pub mod malloc; +// TODO unfinished, unguard feature when ready +#[cfg(feature = "math_libm")] +pub mod math; +pub mod monetary; +// TODO: mqueue.h +// TODO: ndbm.h +pub mod net_if; +pub mod netdb; +pub mod netinet_in; +pub mod netinet_ip; +pub mod netinet_tcp; +// TODO: nl_types.h +// TODO: Remove C header paths.h when cbindgen can export C/Rust strs +// pub mod paths; +pub mod poll; +pub mod pthread; +pub mod pty; +pub mod pwd; +// TODO: re_comp.h (deprecated) +pub mod regex; +// TODO: regexp.h (deprecated) +pub mod sched; +// TODO: search.h +pub mod semaphore; +pub mod setjmp; +pub mod sgtty; +pub mod shadow; +pub mod signal; +pub mod spawn; +// TODO: stdalign.h (likely C implementation) +// stdarg.h implemented in C +// stdatomic.h implemented in C +// stdbool.h implemented in C +// stddef.h implemented in C +// stdint.h implemented in C +pub mod stdio; +pub mod stdlib; +// TODO: stdnoreturn.h (likely C implementation) +pub mod string; +pub mod strings; +// TODO: stropts.h (deprecated) +pub mod sys_auxv; +pub mod sys_epoll; +pub mod sys_eventfd; +pub mod sys_file; +pub mod sys_ioctl; +// TODO: sys/ipc.h +pub mod sys_mman; +// TODO: sys/msg.h +pub mod sys_ptrace; +pub mod sys_resource; +pub mod sys_select; +// TODO: sys/sem.h +// TODO: sys/shm.h +pub mod sys_socket; +pub mod sys_stat; +pub mod sys_statvfs; +#[allow(non_upper_case_globals)] +pub mod sys_syscall; +pub mod sys_time; +#[deprecated] +pub mod sys_timeb; +//pub mod sys_times; +pub mod arch_aarch64_user; +pub mod arch_riscv64_user; +pub mod arch_x64_user; +pub mod sys_signalfd; +#[cfg(not(target_arch = "x86"))] // TODO: x86 +pub mod sys_procfs; +pub mod sys_random; +pub mod sys_timerfd; +pub mod sys_syslog; +pub mod sys_types; +#[allow(non_camel_case_types)] +pub mod sys_types_internal; +pub mod sys_uio; +pub mod sys_un; +pub mod sys_utsname; +pub mod sys_wait; +pub mod tar; +// TODO: term.h (deprecated) +pub mod termios; +// TODO: tgmath.h (likely C implementation) +// TODO: threads.h +pub mod time; +// TODO: uchar.h +// TODO: ucontext.h (deprecated) +// TODO: ulimit.h (deprecated) +// TODO: unctrl.h (deprecated) +pub mod unistd; +#[deprecated] +pub mod utime; +pub mod utmp; +// TODO: utmpx.h +// TODO: varargs.h (deprecated) +pub mod wchar; +pub mod wctype; +// TODO: wordexp.h +// TODO: xti.h (deprecated) diff --git a/src/header/sys_eventfd/cbindgen.toml b/src/header/sys_eventfd/cbindgen.toml index ab821310eb..d6750cc523 100644 --- a/src/header/sys_eventfd/cbindgen.toml +++ b/src/header/sys_eventfd/cbindgen.toml @@ -1,12 +1,8 @@ -sys_includes = ["stdint.h", "stddef.h"] -include_guard = "_SYS_EVENTFD_H" -trailer = """ +sys_includes = ["stdint.h"] +after_includes = """ typedef uint64_t eventfd_t; - -int eventfd(unsigned int initval, int flags); -int eventfd_read(int fd, eventfd_t *value); -int eventfd_write(int fd, eventfd_t value); """ +include_guard = "_SYS_EVENTFD_H" language = "C" style = "Tag" no_includes = true diff --git a/src/header/sys_eventfd/mod.rs b/src/header/sys_eventfd/mod.rs index 04fa30eaa0..f9ad374a7f 100644 --- a/src/header/sys_eventfd/mod.rs +++ b/src/header/sys_eventfd/mod.rs @@ -1,7 +1,58 @@ -use crate::platform::types::{c_int, uint64_t}; +use alloc::format; +use crate::c_str::{CStr, CString}; +use crate::error::{Errno, ResultExt}; +use crate::header::fcntl::{O_CLOEXEC, O_NONBLOCK, O_RDWR}; +use crate::header::errno::EFAULT; +use crate::header::errno::EINVAL; +use crate::platform::{Pal, Sys, types::{c_int, c_uint}}; -pub type eventfd_t = uint64_t; +// Re-export eventfd_t from bits/eventfd.h +pub use crate::header::bits_eventfd::eventfd_t; pub const EFD_SEMAPHORE: c_int = 1; pub const EFD_CLOEXEC: c_int = 0x80000; pub const EFD_NONBLOCK: c_int = 0x800; + +#[unsafe(no_mangle)] +pub extern "C" fn eventfd(initval: c_uint, flags: c_int) -> c_int { + let supported = EFD_CLOEXEC | EFD_NONBLOCK | EFD_SEMAPHORE; + if flags & !supported != 0 { + return Err::(Errno(EINVAL)).or_minus_one_errno(); + } + let sem = if flags & EFD_SEMAPHORE != 0 { 1 } else { 0 }; + let path = format!("/scheme/event/eventfd/{}/{}", initval, sem); + let cpath = match CString::new(path) { + Ok(p) => p, + Err(_) => return Err::(Errno(EINVAL)).or_minus_one_errno(), + }; + + let mut oflag = O_RDWR; + if flags & EFD_CLOEXEC == EFD_CLOEXEC { + oflag |= O_CLOEXEC; + } + if flags & EFD_NONBLOCK == EFD_NONBLOCK { + oflag |= O_NONBLOCK; + } + Sys::open(CStr::borrow(&cpath), oflag, 0).or_minus_one_errno() +} + +#[unsafe(no_mangle)] +pub extern "C" fn eventfd_read(fd: c_int, value: *mut eventfd_t) -> c_int { + if value.is_null() { + return Err::(Errno(EFAULT)).or_minus_one_errno(); + } + let mut buf = [0u8; 8]; + match Sys::read(fd, &mut buf) { + Ok(8) => { unsafe { *value = u64::from_ne_bytes(buf); } 0 } + _ => -1, + } +} + +#[unsafe(no_mangle)] +pub extern "C" fn eventfd_write(fd: c_int, value: eventfd_t) -> c_int { + let buf = value.to_ne_bytes(); + match Sys::write(fd, &buf) { + Ok(8) => 0, + _ => -1, + } +} diff --git a/src/header/sys_eventfd/mod.rs.orig b/src/header/sys_eventfd/mod.rs.orig new file mode 100644 index 0000000000..04fa30eaa0 --- /dev/null +++ b/src/header/sys_eventfd/mod.rs.orig @@ -0,0 +1,7 @@ +use crate::platform::types::{c_int, uint64_t}; + +pub type eventfd_t = uint64_t; + +pub const EFD_SEMAPHORE: c_int = 1; +pub const EFD_CLOEXEC: c_int = 0x80000; +pub const EFD_NONBLOCK: c_int = 0x800;