23#error "port/posix is host-only and must never be compiled or linked into target firmware."
41#if defined(__linux__) || defined(__APPLE__)
42#include <sys/syscall.h>
59#ifndef RENAME_NOREPLACE
61#define RENAME_NOREPLACE (1U << 0U)
80#if defined(__linux__) && defined(SYS_renameat2)
82 const long result = syscall(SYS_renameat2, -1,
"x", -1,
"y",
RENAME_NOREPLACE);
86 return errno == EBADF;
87#elif defined(__APPLE__)
89 const int result = renameatx_np(-1,
"x", -1,
"y", RENAME_EXCL);
93 return errno == EBADF;
124 if (path[0] !=
'\0') {
125 const char* anchor = (path[0] ==
'/') ?
"/" :
".";
158 while (**cursor ==
'/') {
163 *cursor = &(*cursor)[1];
190 uint16_t length = 0U;
194 const char value = **cursor;
219 out_component[length] = value;
221 *cursor = &(*cursor)[1];
224 out_component[length] =
'\0';
252 out_component[0] =
'\0';
255 if (**cursor ==
'\0') {
320 if (
strcmp(component,
".") != 0) {
348 *out_complete =
false;
350 for (uint16_t component = 0U; component < (uint16_t)
k_fw_fs_path_cap; ++component) {
360 *out_complete =
true;
400 const char* cursor = path;
401 uint16_t consumed = 0U;
403 bool complete =
false;
463 .max_file_bytes = (uint64_t)INT64_MAX,
495 if (out ==
nullptr) {
498 if (state ==
nullptr) {
501 if (cfg ==
nullptr) {
532 if (state ==
nullptr) {
#define O_DIRECTORY
No-op directory-open fallback for hosts lacking the flag.
Architecture-neutral filesystem namespace, stream, and transaction ports.
#define RENAME_NOREPLACE
Host flag value for atomic no-replace rename probing.
ra8_err_t priv_fs_posix_component_open(int parent_fd, const char *component, int *out_fd)
Open one validated directory component without following its pathname.
ra8_err_t priv_fs_posix_bind_interfaces(fw_fs_t *out, fw_fs_posix_state_t *state, const fw_fs_caps_t *caps)
Bind the immutable POSIX operation tables to initialized state.
#define O_NOFOLLOW
Zero fallback paired with explicit no-follow metadata validation.
#define O_CLOEXEC
Zero fallback when the host lacks close-on-exec open flags.
Root-confined hosted POSIX adapter for fw_if_fs.
static ra8_err_t internal_root_skip_slashes(const char **cursor, uint16_t *consumed)
Skip repeated path separators under the complete-path bound.
static ra8_err_t internal_root_base_open(const char *path, const char **out_cursor, int *out_fd)
Open the descriptor anchor for an absolute or relative root path.
ra8_err_t fw_fs_posix_deinit(fw_fs_posix_state_t *state)
Close the root descriptor; no bound operation is valid afterward.
static ra8_err_t internal_root_walk_step(int *current, const char *component)
Apply one scanned component to the current root descriptor.
static ra8_err_t internal_root_name_copy(const char **cursor, uint16_t *consumed, char *out_component)
Copy one bounded root component and advance its path cursor.
static ra8_err_t internal_root_component_scan(const char **cursor, uint16_t *consumed, char *out_component, bool *out_end)
Scan one bounded component while normalizing repeated slashes.
static ra8_err_t internal_root_open_step(int *current, const char *component)
Descend into one root component and retire the previous descriptor.
static ra8_err_t internal_root_open(const char *path, int *out_fd)
Open one caller-selected confinement root component by component.
static ra8_err_t internal_root_walk(const char **cursor, uint16_t *consumed, int *current, bool *out_complete)
Walk every remaining root component beneath an owned anchor.
static bool internal_atomic_noreplace_available(void)
Probe whether the host provides an atomic no-replace rename.
static void internal_caps(const fw_fs_posix_state_t *state, fw_fs_caps_t *out)
Assemble capabilities for one initialized POSIX adapter.
ra8_err_t fw_fs_posix_init(fw_fs_t *out, fw_fs_posix_state_t *state, const fw_fs_posix_cfg_t *cfg)
Open/configure a root-confined POSIX binding.
static void internal_state_reset(fw_fs_posix_state_t *state)
Restore one inactive POSIX adapter state to its public sentinel.
ra8_err_t priv_fs_posix_close_fd(int *fd)
Close exactly once and invalidate the caller's descriptor.
ra8_err_t priv_fs_posix_close_fd_preserve(int *fd, ra8_err_t primary)
Close one owned descriptor while preserving a primary status.
ra8_err_t priv_fs_posix_errno(int value)
Map one captured errno value into ra8_err_t.
Shared errno/descriptor helpers for the POSIX filesystem port.
@ k_posix_max_open_files
Truthful hosted descriptor capacity.
@ k_posix_component_cap
Component buffer including NUL.
@ k_fw_fs_path_cap
Largest portable path including its NUL.
@ k_fw_fs_cap_durable_directory_sync
Namespace changes can be made durable.
@ k_fw_fs_cap_durable_file_sync
Successful file sync reaches durable media.
@ k_fw_fs_cap_symlinks
Symbolic links may be represented by the backend.
@ k_fw_fs_cap_stream
Regular-file stream operations are available.
@ k_fw_fs_cap_namespace
Metadata and namespace operations are available.
@ k_fw_fs_cap_space_query
Volume capacity and available bytes can be queried.
@ k_fw_fs_cap_rejects_symlink_walk
Path traversal refuses symbolic-link components.
@ k_fw_fs_cap_removable_media
The backing volume may disappear at runtime.
@ k_fw_fs_cap_same_volume_rename
Rename is supported within one backend volume.
@ k_fw_fs_cap_modified_time
Modification timestamps may be reported as valid.
@ k_fw_fs_cap_create_exclusive
Open can atomically require that its leaf be absent.
@ k_fw_fs_cap_file_sync
An explicit file-sync operation is available.
@ k_fw_fs_cap_accessed_time
Access timestamps may be reported as valid.
@ k_fw_fs_cap_atomic_noreplace
Rename can atomically reject an existing destination.
@ k_fw_fs_cap_created_time
Creation timestamps may be reported as valid.
@ k_fw_fs_cap_transactions
Staged publication operations are available.
@ k_fw_fs_cap_atomic_replace
Rename can atomically replace an existing destination.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_LOOP_BOUND(ceiling)
NASA Power-of-10 Rule 2: bind ONE loop to a compile-time ceiling.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_err_exists
Item already exists – cannot create again.
@ k_ra8_err_not_initialized
Module not initialized – _init() not yet called successfully.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
int strcmp(const char *s1, const char *s2)
Compare two null-terminated strings.
Static properties and workspace requirements of one bound port.
uint32_t flags
OR of fw_fs_capability_t.
POSIX composition-root settings.
const char * root_path
Existing host directory used as /.
bool removable_media
Truthful property of the selected root.
Caller-owned POSIX adapter state.
bool atomic_noreplace
Runtime-probed rename guarantee.
bool removable_media
Capability input.
bool initialized
Lifecycle guard.
uint32_t transaction_id
Per-binding stage-name counter.
int root_fd
Open descriptor, or -1 while inactive.
One complete composition-root filesystem binding.
POSIX state placed in caller directory workspace.
POSIX state placed in caller file workspace.
POSIX state placed in caller transaction workspace.