Skip to main content

Module ffi

Module ffi 

Source
Expand description

C ABI for the block-device framework.

Every sister crate (qcow2 reader, partition probe, fs-* drivers) speaks through the FsCoreDevice handle defined here, so consumers (Swift FSKit modules, Go callers, C programs) only learn one device-handle type and one error convention.

§Conventions

  • Handles are opaque *mut FsCoreDevice. Allocate via a constructor in one of the sister crates (e.g. qcow2_open from rust-img-qcow2), free via fs_core_device_close regardless of which crate created it.
  • Error reporting is errno-style: every fallible function returns an FsCoreErrorCode (0 = OK, non-zero = failure) and stashes a human message in a thread-local. Read it via fs_core_last_error_message.
  • Every entry point catches Rust panics with catch_unwind and maps them to FsCoreErrorCode::Panic. Crossing an FFI boundary while unwinding is UB; the catch-net is non-negotiable.
  • Thread safety: handles wrap Arc<dyn BlockDevice>, which is Send + Sync by trait bound. Multiple threads can call read/write concurrently as long as the underlying device’s locking permits it.

Structs§

FsCoreCallbackCfg
Configuration passed to fs_core_device_from_callbacks.
FsCoreDevice
Opaque handle wrapping an Arc<dyn BlockDevice>. Allocated by sister crates’ constructors and freed via fs_core_device_close.

Enums§

FsCoreErrorCode
Numeric error codes mirrored across every sister crate’s C ABI.

Functions§

ffi_guard
Helper for sister crates: run body, catch panics, map errors to codes, stash the message in the thread-local. Returns the error code.
ffi_guard_cleanup
Run a cleanup body — a close, a free — catching a panic so it cannot unwind into C, and leaving the error slot untouched.
ffi_guard_or
Run body, catching a panic and returning fail instead — and recording the panic’s message where a caller can read it.
fs_core_device_close⚠
Free a device handle. Safe to call with NULL (no-op).
fs_core_device_flush⚠
Flush pending writes to stable storage.
fs_core_device_from_callbacks⚠
Build an FsCoreDevice backed by host-provided callbacks. Returns NULL on failure (config null, read callback null, etc.) and stashes detail in the thread-local last-error.
fs_core_device_is_writable⚠
True if write_at is likely to succeed. Returns false on NULL.
fs_core_device_read_at⚠
Read exactly len bytes from offset into buf. buf must be at least len bytes. Returns an FsCoreErrorCode.
fs_core_device_size_bytes⚠
Total device size in bytes. Returns 0 if handle is NULL.
fs_core_device_slice_ro⚠
Read-only slice. Writes via the returned handle return FS_CORE_READ_ONLY regardless of the parent’s writability.
fs_core_device_slice_rw⚠
Read-write slice. Writes are forwarded to the parent at start + offset; writes outside [0, length) return FS_CORE_OUT_OF_BOUNDS. If the parent reports is_writable() == false, write attempts return FS_CORE_READ_ONLY.
fs_core_device_write_at⚠
Write exactly len bytes from buf to offset. Returns ReadOnly for read-only devices.
fs_core_file_open⚠
Open path (NUL-terminated UTF-8) as a FileDevice and return a handle. Pass writable=true for RW. On failure returns NULL and the thread-local last-error has detail.
fs_core_last_error_message
Return a pointer to the calling thread’s most recent error message, or NULL if there is none. The pointer is owned by the framework and remains valid until the next FFI call on this thread.
panic_message
What a caught panic actually said.
set_last_error
Stash a message in the thread-local, replacing any previous one. Public to sister crates so they can populate it for their own error paths.

Type Aliases§

FsCoreFlushCb
Flush/fsync callback. NULL → flush is a no-op.
FsCoreReadCb
Read callback. Returns 0 on success, non-zero (errno-like) on failure. Must fully fill len bytes — short reads are treated as I/O errors.
FsCoreWriteCb
Write callback. NULL → device is read-only.