about summary refs log tree commit diff
diff options
context:
space:
mode:
authorjoboet <jonasboettiger@icloud.com>2025-05-05 12:16:40 +0200
committerjoboet <jonasboettiger@icloud.com>2025-05-05 12:16:40 +0200
commit7845c011dd3bdfb5eaa461476f5f7d0f3aa16dfc (patch)
tree8d1ea8f4d96fa08e3442e2cbbd68fef183fe521e
parent54d024e4bf462c77a86c4126d7e66d89b64f053a (diff)
downloadrust-7845c011dd3bdfb5eaa461476f5f7d0f3aa16dfc.tar.gz
rust-7845c011dd3bdfb5eaa461476f5f7d0f3aa16dfc.zip
collect all Fuchsia bindings into the `fuchsia` module
The Fuchsia bindings are currently spread out across multiple modules in `sys/pal/unix` leading to unnecessary duplication. This PR moves all of these definitions into `sys::pal::unix::fuchsia` and additionally:
* deduplicates the definitions
* makes the error names consistent
* marks some extern functions as safe
* removes unused items (there's no need to maintain these bindings if we're not going to use them)
* removes the documentation for the definitions (contributors should always consult the platform documentation, duplicating that here is just an extra maintenance burden)
-rw-r--r--library/std/src/sys/pal/unix/fuchsia.rs321
-rw-r--r--library/std/src/sys/pal/unix/futex.rs54
-rw-r--r--library/std/src/sys/pal/unix/thread.rs19
-rw-r--r--library/std/src/sys/process/unix/fuchsia.rs4
-rw-r--r--library/std/src/sys/sync/mutex/fuchsia.rs6
5 files changed, 122 insertions, 282 deletions
diff --git a/library/std/src/sys/pal/unix/fuchsia.rs b/library/std/src/sys/pal/unix/fuchsia.rs
index 7932bd26d76..c118dee6247 100644
--- a/library/std/src/sys/pal/unix/fuchsia.rs
+++ b/library/std/src/sys/pal/unix/fuchsia.rs
@@ -1,48 +1,35 @@
-#![allow(non_camel_case_types, unused)]
+#![expect(non_camel_case_types)]
 
-use libc::{c_int, c_void, size_t};
+use libc::size_t;
 
+use crate::ffi::{c_char, c_int, c_void};
 use crate::io;
-use crate::mem::MaybeUninit;
-use crate::os::raw::c_char;
 
-pub type zx_handle_t = u32;
-pub type zx_vaddr_t = usize;
-pub type zx_rights_t = u32;
-pub type zx_status_t = i32;
-
-pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
+//////////
+// Time //
+//////////
 
 pub type zx_time_t = i64;
-pub const ZX_TIME_INFINITE: zx_time_t = i64::MAX;
-
-pub type zx_signals_t = u32;
-
-pub const ZX_OBJECT_SIGNAL_3: zx_signals_t = 1 << 3;
 
-pub const ZX_TASK_TERMINATED: zx_signals_t = ZX_OBJECT_SIGNAL_3;
+pub const ZX_TIME_INFINITE: zx_time_t = i64::MAX;
 
-pub const ZX_RIGHT_SAME_RIGHTS: zx_rights_t = 1 << 31;
+unsafe extern "C" {
+    pub safe fn zx_clock_get_monotonic() -> zx_time_t;
+}
 
-// The upper four bits gives the minor version.
-pub type zx_object_info_topic_t = u32;
+/////////////
+// Handles //
+/////////////
 
-pub const ZX_INFO_PROCESS: zx_object_info_topic_t = 3 | (1 << 28);
+pub type zx_handle_t = u32;
 
-pub type zx_info_process_flags_t = u32;
+pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
 
-pub fn zx_cvt<T>(t: T) -> io::Result<T>
-where
-    T: TryInto<zx_status_t> + Copy,
-{
-    if let Ok(status) = TryInto::try_into(t) {
-        if status < 0 { Err(io::Error::from_raw_os_error(status)) } else { Ok(t) }
-    } else {
-        Err(io::Error::last_os_error())
-    }
+unsafe extern "C" {
+    pub fn zx_handle_close(handle: zx_handle_t) -> zx_status_t;
 }
 
-// Safe wrapper around zx_handle_t
+/// A safe wrapper around `zx_handle_t`.
 pub struct Handle {
     raw: zx_handle_t,
 }
@@ -65,6 +52,66 @@ impl Drop for Handle {
     }
 }
 
+///////////
+// Futex //
+///////////
+
+pub type zx_futex_t = crate::sync::atomic::Atomic<u32>;
+
+unsafe extern "C" {
+    pub fn zx_object_wait_one(
+        handle: zx_handle_t,
+        signals: zx_signals_t,
+        timeout: zx_time_t,
+        pending: *mut zx_signals_t,
+    ) -> zx_status_t;
+
+    pub fn zx_futex_wait(
+        value_ptr: *const zx_futex_t,
+        current_value: zx_futex_t,
+        new_futex_owner: zx_handle_t,
+        deadline: zx_time_t,
+    ) -> zx_status_t;
+    pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t;
+    pub fn zx_futex_wake_single_owner(value_ptr: *const zx_futex_t) -> zx_status_t;
+    pub safe fn zx_thread_self() -> zx_handle_t;
+}
+
+////////////////
+// Properties //
+////////////////
+
+pub const ZX_PROP_NAME: u32 = 3;
+
+unsafe extern "C" {
+    pub fn zx_object_set_property(
+        handle: zx_handle_t,
+        property: u32,
+        value: *const libc::c_void,
+        value_size: libc::size_t,
+    ) -> zx_status_t;
+}
+
+/////////////
+// Signals //
+/////////////
+
+pub type zx_signals_t = u32;
+
+pub const ZX_OBJECT_SIGNAL_3: zx_signals_t = 1 << 3;
+pub const ZX_TASK_TERMINATED: zx_signals_t = ZX_OBJECT_SIGNAL_3;
+
+/////////////////
+// Object info //
+/////////////////
+
+// The upper four bits gives the minor version.
+pub type zx_object_info_topic_t = u32;
+
+pub const ZX_INFO_PROCESS: zx_object_info_topic_t = 3 | (1 << 28);
+
+pub type zx_info_process_flags_t = u32;
+
 // Returned for topic ZX_INFO_PROCESS
 #[derive(Default)]
 #[repr(C)]
@@ -76,25 +123,6 @@ pub struct zx_info_process_t {
 }
 
 unsafe extern "C" {
-    pub fn zx_job_default() -> zx_handle_t;
-
-    pub fn zx_task_kill(handle: zx_handle_t) -> zx_status_t;
-
-    pub fn zx_handle_close(handle: zx_handle_t) -> zx_status_t;
-
-    pub fn zx_handle_duplicate(
-        handle: zx_handle_t,
-        rights: zx_rights_t,
-        out: *const zx_handle_t,
-    ) -> zx_handle_t;
-
-    pub fn zx_object_wait_one(
-        handle: zx_handle_t,
-        signals: zx_signals_t,
-        timeout: zx_time_t,
-        pending: *mut zx_signals_t,
-    ) -> zx_status_t;
-
     pub fn zx_object_get_info(
         handle: zx_handle_t,
         topic: u32,
@@ -105,6 +133,10 @@ unsafe extern "C" {
     ) -> zx_status_t;
 }
 
+///////////////
+// Processes //
+///////////////
+
 #[derive(Default)]
 #[repr(C)]
 pub struct fdio_spawn_action_t {
@@ -130,6 +162,8 @@ unsafe extern "C" {
 
     pub fn fdio_fd_clone(fd: c_int, out_handle: *mut zx_handle_t) -> zx_status_t;
     pub fn fdio_fd_create(handle: zx_handle_t, fd: *mut c_int) -> zx_status_t;
+
+    pub fn zx_task_kill(handle: zx_handle_t) -> zx_status_t;
 }
 
 // fdio_spawn_etc flags
@@ -137,173 +171,34 @@ unsafe extern "C" {
 pub const FDIO_SPAWN_CLONE_JOB: u32 = 0x0001;
 pub const FDIO_SPAWN_CLONE_LDSVC: u32 = 0x0002;
 pub const FDIO_SPAWN_CLONE_NAMESPACE: u32 = 0x0004;
-pub const FDIO_SPAWN_CLONE_STDIO: u32 = 0x0008;
 pub const FDIO_SPAWN_CLONE_ENVIRON: u32 = 0x0010;
 pub const FDIO_SPAWN_CLONE_UTC_CLOCK: u32 = 0x0020;
-pub const FDIO_SPAWN_CLONE_ALL: u32 = 0xFFFF;
 
 // fdio_spawn_etc actions
 
-pub const FDIO_SPAWN_ACTION_CLONE_FD: u32 = 0x0001;
 pub const FDIO_SPAWN_ACTION_TRANSFER_FD: u32 = 0x0002;
 
-// Errors
-
-#[allow(unused)]
-pub const ERR_INTERNAL: zx_status_t = -1;
-
-// ERR_NOT_SUPPORTED: The operation is not implemented, supported,
-// or enabled.
-#[allow(unused)]
-pub const ERR_NOT_SUPPORTED: zx_status_t = -2;
-
-// ERR_NO_RESOURCES: The system was not able to allocate some resource
-// needed for the operation.
-#[allow(unused)]
-pub const ERR_NO_RESOURCES: zx_status_t = -3;
-
-// ERR_NO_MEMORY: The system was not able to allocate memory needed
-// for the operation.
-#[allow(unused)]
-pub const ERR_NO_MEMORY: zx_status_t = -4;
-
-// ERR_CALL_FAILED: The second phase of zx_channel_call(; did not complete
-// successfully.
-#[allow(unused)]
-pub const ERR_CALL_FAILED: zx_status_t = -5;
-
-// ERR_INTERRUPTED_RETRY: The system call was interrupted, but should be
-// retried.  This should not be seen outside of the VDSO.
-#[allow(unused)]
-pub const ERR_INTERRUPTED_RETRY: zx_status_t = -6;
-
-// ======= Parameter errors =======
-// ERR_INVALID_ARGS: an argument is invalid, ex. null pointer
-#[allow(unused)]
-pub const ERR_INVALID_ARGS: zx_status_t = -10;
-
-// ERR_BAD_HANDLE: A specified handle value does not refer to a handle.
-#[allow(unused)]
-pub const ERR_BAD_HANDLE: zx_status_t = -11;
-
-// ERR_WRONG_TYPE: The subject of the operation is the wrong type to
-// perform the operation.
-// Example: Attempting a message_read on a thread handle.
-#[allow(unused)]
-pub const ERR_WRONG_TYPE: zx_status_t = -12;
-
-// ERR_BAD_SYSCALL: The specified syscall number is invalid.
-#[allow(unused)]
-pub const ERR_BAD_SYSCALL: zx_status_t = -13;
-
-// ERR_OUT_OF_RANGE: An argument is outside the valid range for this
-// operation.
-#[allow(unused)]
-pub const ERR_OUT_OF_RANGE: zx_status_t = -14;
-
-// ERR_BUFFER_TOO_SMALL: A caller provided buffer is too small for
-// this operation.
-#[allow(unused)]
-pub const ERR_BUFFER_TOO_SMALL: zx_status_t = -15;
-
-// ======= Precondition or state errors =======
-// ERR_BAD_STATE: operation failed because the current state of the
-// object does not allow it, or a precondition of the operation is
-// not satisfied
-#[allow(unused)]
-pub const ERR_BAD_STATE: zx_status_t = -20;
-
-// ERR_TIMED_OUT: The time limit for the operation elapsed before
-// the operation completed.
-#[allow(unused)]
-pub const ERR_TIMED_OUT: zx_status_t = -21;
-
-// ERR_SHOULD_WAIT: The operation cannot be performed currently but
-// potentially could succeed if the caller waits for a prerequisite
-// to be satisfied, for example waiting for a handle to be readable
-// or writable.
-// Example: Attempting to read from a message pipe that has no
-// messages waiting but has an open remote will return ERR_SHOULD_WAIT.
-// Attempting to read from a message pipe that has no messages waiting
-// and has a closed remote end will return ERR_REMOTE_CLOSED.
-#[allow(unused)]
-pub const ERR_SHOULD_WAIT: zx_status_t = -22;
-
-// ERR_CANCELED: The in-progress operation (e.g., a wait) has been
-// // canceled.
-#[allow(unused)]
-pub const ERR_CANCELED: zx_status_t = -23;
-
-// ERR_PEER_CLOSED: The operation failed because the remote end
-// of the subject of the operation was closed.
-#[allow(unused)]
-pub const ERR_PEER_CLOSED: zx_status_t = -24;
-
-// ERR_NOT_FOUND: The requested entity is not found.
-#[allow(unused)]
-pub const ERR_NOT_FOUND: zx_status_t = -25;
-
-// ERR_ALREADY_EXISTS: An object with the specified identifier
-// already exists.
-// Example: Attempting to create a file when a file already exists
-// with that name.
-#[allow(unused)]
-pub const ERR_ALREADY_EXISTS: zx_status_t = -26;
-
-// ERR_ALREADY_BOUND: The operation failed because the named entity
-// is already owned or controlled by another entity. The operation
-// could succeed later if the current owner releases the entity.
-#[allow(unused)]
-pub const ERR_ALREADY_BOUND: zx_status_t = -27;
-
-// ERR_UNAVAILABLE: The subject of the operation is currently unable
-// to perform the operation.
-// Note: This is used when there's no direct way for the caller to
-// observe when the subject will be able to perform the operation
-// and should thus retry.
-#[allow(unused)]
-pub const ERR_UNAVAILABLE: zx_status_t = -28;
-
-// ======= Permission check errors =======
-// ERR_ACCESS_DENIED: The caller did not have permission to perform
-// the specified operation.
-#[allow(unused)]
-pub const ERR_ACCESS_DENIED: zx_status_t = -30;
-
-// ======= Input-output errors =======
-// ERR_IO: Otherwise unspecified error occurred during I/O.
-#[allow(unused)]
-pub const ERR_IO: zx_status_t = -40;
-
-// ERR_REFUSED: The entity the I/O operation is being performed on
-// rejected the operation.
-// Example: an I2C device NAK'ing a transaction or a disk controller
-// rejecting an invalid command.
-#[allow(unused)]
-pub const ERR_IO_REFUSED: zx_status_t = -41;
-
-// ERR_IO_DATA_INTEGRITY: The data in the operation failed an integrity
-// check and is possibly corrupted.
-// Example: CRC or Parity error.
-#[allow(unused)]
-pub const ERR_IO_DATA_INTEGRITY: zx_status_t = -42;
-
-// ERR_IO_DATA_LOSS: The data in the operation is currently unavailable
-// and may be permanently lost.
-// Example: A disk block is irrecoverably damaged.
-#[allow(unused)]
-pub const ERR_IO_DATA_LOSS: zx_status_t = -43;
-
-// Filesystem specific errors
-#[allow(unused)]
-pub const ERR_BAD_PATH: zx_status_t = -50;
-#[allow(unused)]
-pub const ERR_NOT_DIR: zx_status_t = -51;
-#[allow(unused)]
-pub const ERR_NOT_FILE: zx_status_t = -52;
-// ERR_FILE_BIG: A file exceeds a filesystem-specific size limit.
-#[allow(unused)]
-pub const ERR_FILE_BIG: zx_status_t = -53;
-// ERR_NO_SPACE: Filesystem or device space is exhausted.
-#[allow(unused)]
-pub const ERR_NO_SPACE: zx_status_t = -54;
+////////////
+// Errors //
+////////////
+
+pub type zx_status_t = i32;
+
+pub const ZX_OK: zx_status_t = 0;
+pub const ZX_ERR_NOT_SUPPORTED: zx_status_t = -2;
+pub const ZX_ERR_INVALID_ARGS: zx_status_t = -10;
+pub const ZX_ERR_BAD_HANDLE: zx_status_t = -11;
+pub const ZX_ERR_WRONG_TYPE: zx_status_t = -12;
+pub const ZX_ERR_BAD_STATE: zx_status_t = -20;
+pub const ZX_ERR_TIMED_OUT: zx_status_t = -21;
+
+pub fn zx_cvt<T>(t: T) -> io::Result<T>
+where
+    T: TryInto<zx_status_t> + Copy,
+{
+    if let Ok(status) = TryInto::try_into(t) {
+        if status < 0 { Err(io::Error::from_raw_os_error(status)) } else { Ok(t) }
+    } else {
+        Err(io::Error::last_os_error())
+    }
+}
diff --git a/library/std/src/sys/pal/unix/futex.rs b/library/std/src/sys/pal/unix/futex.rs
index 8d89163c42c..c23278bdf5e 100644
--- a/library/std/src/sys/pal/unix/futex.rs
+++ b/library/std/src/sys/pal/unix/futex.rs
@@ -255,66 +255,28 @@ pub fn futex_wake_all(futex: &Atomic<u32>) {
 }
 
 #[cfg(target_os = "fuchsia")]
-pub mod zircon {
-    pub type zx_futex_t = crate::sync::atomic::Atomic<u32>;
-    pub type zx_handle_t = u32;
-    pub type zx_status_t = i32;
-    pub type zx_time_t = i64;
-
-    pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
-
-    pub const ZX_TIME_INFINITE: zx_time_t = zx_time_t::MAX;
-
-    pub const ZX_OK: zx_status_t = 0;
-    pub const ZX_ERR_INVALID_ARGS: zx_status_t = -10;
-    pub const ZX_ERR_BAD_HANDLE: zx_status_t = -11;
-    pub const ZX_ERR_WRONG_TYPE: zx_status_t = -12;
-    pub const ZX_ERR_BAD_STATE: zx_status_t = -20;
-    pub const ZX_ERR_TIMED_OUT: zx_status_t = -21;
-
-    unsafe extern "C" {
-        pub fn zx_clock_get_monotonic() -> zx_time_t;
-        pub fn zx_futex_wait(
-            value_ptr: *const zx_futex_t,
-            current_value: zx_futex_t,
-            new_futex_owner: zx_handle_t,
-            deadline: zx_time_t,
-        ) -> zx_status_t;
-        pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t;
-        pub fn zx_futex_wake_single_owner(value_ptr: *const zx_futex_t) -> zx_status_t;
-        pub fn zx_thread_self() -> zx_handle_t;
-    }
-}
-
-#[cfg(target_os = "fuchsia")]
 pub fn futex_wait(futex: &Atomic<u32>, expected: u32, timeout: Option<Duration>) -> bool {
+    use super::fuchsia::*;
+
     // Sleep forever if the timeout is longer than fits in a i64.
     let deadline = timeout
-        .and_then(|d| {
-            i64::try_from(d.as_nanos())
-                .ok()?
-                .checked_add(unsafe { zircon::zx_clock_get_monotonic() })
-        })
-        .unwrap_or(zircon::ZX_TIME_INFINITE);
+        .and_then(|d| i64::try_from(d.as_nanos()).ok()?.checked_add(zx_clock_get_monotonic()))
+        .unwrap_or(ZX_TIME_INFINITE);
 
     unsafe {
-        zircon::zx_futex_wait(
-            futex,
-            core::sync::atomic::AtomicU32::new(expected),
-            zircon::ZX_HANDLE_INVALID,
-            deadline,
-        ) != zircon::ZX_ERR_TIMED_OUT
+        zx_futex_wait(futex, zx_futex_t::new(expected), ZX_HANDLE_INVALID, deadline)
+            != ZX_ERR_TIMED_OUT
     }
 }
 
 // Fuchsia doesn't tell us how many threads are woken up, so this always returns false.
 #[cfg(target_os = "fuchsia")]
 pub fn futex_wake(futex: &Atomic<u32>) -> bool {
-    unsafe { zircon::zx_futex_wake(futex, 1) };
+    unsafe { super::fuchsia::zx_futex_wake(futex, 1) };
     false
 }
 
 #[cfg(target_os = "fuchsia")]
 pub fn futex_wake_all(futex: &Atomic<u32>) {
-    unsafe { zircon::zx_futex_wake(futex, u32::MAX) };
+    unsafe { super::fuchsia::zx_futex_wake(futex, u32::MAX) };
 }
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 4cdc2eaf0e5..afda7c65e10 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -22,23 +22,6 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 256 * 1024;
 #[cfg(any(target_os = "espidf", target_os = "nuttx"))]
 pub const DEFAULT_MIN_STACK_SIZE: usize = 0; // 0 indicates that the stack size configured in the ESP-IDF/NuttX menuconfig system should be used
 
-#[cfg(target_os = "fuchsia")]
-mod zircon {
-    type zx_handle_t = u32;
-    type zx_status_t = i32;
-    pub const ZX_PROP_NAME: u32 = 3;
-
-    unsafe extern "C" {
-        pub fn zx_object_set_property(
-            handle: zx_handle_t,
-            property: u32,
-            value: *const libc::c_void,
-            value_size: libc::size_t,
-        ) -> zx_status_t;
-        pub fn zx_thread_self() -> zx_handle_t;
-    }
-}
-
 pub struct Thread {
     id: libc::pthread_t,
 }
@@ -216,7 +199,7 @@ impl Thread {
 
     #[cfg(target_os = "fuchsia")]
     pub fn set_name(name: &CStr) {
-        use self::zircon::*;
+        use super::fuchsia::*;
         unsafe {
             zx_object_set_property(
                 zx_thread_self(),
diff --git a/library/std/src/sys/process/unix/fuchsia.rs b/library/std/src/sys/process/unix/fuchsia.rs
index 0de32ecffd4..eb62bbd808e 100644
--- a/library/std/src/sys/process/unix/fuchsia.rs
+++ b/library/std/src/sys/process/unix/fuchsia.rs
@@ -81,7 +81,7 @@ impl Command {
 
                 let mut handle = ZX_HANDLE_INVALID;
                 let status = fdio_fd_clone(target_fd, &mut handle);
-                if status == ERR_INVALID_ARGS || status == ERR_NOT_SUPPORTED {
+                if status == ZX_ERR_INVALID_ARGS || status == ZX_ERR_NOT_SUPPORTED {
                     // This descriptor is closed; skip it rather than generating an
                     // error.
                     return Ok(Default::default());
@@ -197,7 +197,7 @@ impl Process {
                 zx_object_wait_one(self.handle.raw(), ZX_TASK_TERMINATED, 0, ptr::null_mut());
             match status {
                 0 => {} // Success
-                x if x == ERR_TIMED_OUT => {
+                x if x == ZX_ERR_TIMED_OUT => {
                     return Ok(None);
                 }
                 _ => {
diff --git a/library/std/src/sys/sync/mutex/fuchsia.rs b/library/std/src/sys/sync/mutex/fuchsia.rs
index 3d388a4564a..cbb1926530f 100644
--- a/library/std/src/sys/sync/mutex/fuchsia.rs
+++ b/library/std/src/sys/sync/mutex/fuchsia.rs
@@ -39,7 +39,7 @@
 
 use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
 use crate::sync::atomic::{Atomic, AtomicU32};
-use crate::sys::futex::zircon::{
+use crate::sys::fuchsia::{
     ZX_ERR_BAD_HANDLE, ZX_ERR_BAD_STATE, ZX_ERR_INVALID_ARGS, ZX_ERR_TIMED_OUT, ZX_ERR_WRONG_TYPE,
     ZX_OK, ZX_TIME_INFINITE, zx_futex_wait, zx_futex_wake_single_owner, zx_handle_t,
     zx_thread_self,
@@ -83,13 +83,13 @@ impl Mutex {
 
     #[inline]
     pub fn try_lock(&self) -> bool {
-        let thread_self = unsafe { zx_thread_self() };
+        let thread_self = zx_thread_self();
         self.futex.compare_exchange(UNLOCKED, to_state(thread_self), Acquire, Relaxed).is_ok()
     }
 
     #[inline]
     pub fn lock(&self) {
-        let thread_self = unsafe { zx_thread_self() };
+        let thread_self = zx_thread_self();
         if let Err(state) =
             self.futex.compare_exchange(UNLOCKED, to_state(thread_self), Acquire, Relaxed)
         {