ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
fw_if_fs_posix_bind.c File Reference

Lifecycle and capability binding for the hosted POSIX filesystem. More...

#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "fw_if_fs_posix.h"
#include "ra8_attributes.h"
#include "fw_if_fs.h"
#include "fw_if_fs_posix_internal.h"
#include "ra8_err.h"
Include dependency graph for fw_if_fs_posix_bind.c:

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 Request GNU descriptor-relative syscall declarations on Linux.
#define O_CLOEXEC   (0)
 Zero fallback when the host lacks close-on-exec open flags.
#define O_NOFOLLOW   (0)
 Zero fallback paired with explicit no-follow metadata validation.
#define RENAME_NOREPLACE   (1U << 0U)
 Host flag value for atomic no-replace rename probing.

Functions

static bool internal_atomic_noreplace_available (void)
 Probe whether the host provides an atomic no-replace rename.
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.
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_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_walk_step (int *current, const char *component)
 Apply one scanned component to the current root descriptor.
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 ra8_err_t internal_root_open (const char *path, int *out_fd)
 Open one caller-selected confinement root component by component.
static void internal_state_reset (fw_fs_posix_state_t *state)
 Restore one inactive POSIX adapter state to its public sentinel.
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.
ra8_err_t fw_fs_posix_deinit (fw_fs_posix_state_t *state)
 Close the root descriptor; no bound operation is valid afterward.

Detailed Description

Lifecycle and capability binding for the hosted POSIX filesystem.

Tag
[Ring 4 / Host Port] {World: Host}

Opens and owns the confined root descriptor, denies symlink roots on Linux, and verifies Darwin's exact filesystem-root aliases before opening their canonical components no-follow. It also probes the host's atomic no-replace primitive, assembles truthful workspace and durability capabilities, and binds those properties to the POSIX operation tables. Keeping lifecycle composition separate makes descriptor ownership and initialization failure handling explicit.

Definition in file fw_if_fs_posix_bind.c.

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Request GNU descriptor-relative syscall declarations on Linux.

Definition at line 28 of file fw_if_fs_posix_bind.c.

◆ O_CLOEXEC

#define O_CLOEXEC   (0)

Zero fallback when the host lacks close-on-exec open flags.

Definition at line 51 of file fw_if_fs_posix_bind.c.

◆ O_NOFOLLOW

#define O_NOFOLLOW   (0)

Zero fallback paired with explicit no-follow metadata validation.

Definition at line 56 of file fw_if_fs_posix_bind.c.

◆ RENAME_NOREPLACE

#define RENAME_NOREPLACE   (1U << 0U)

Host flag value for atomic no-replace rename probing.

Definition at line 61 of file fw_if_fs_posix_bind.c.

Function Documentation

◆ fw_fs_posix_deinit()

◆ fw_fs_posix_init()

ra8_err_t fw_fs_posix_init ( fw_fs_t * out,
fw_fs_posix_state_t * state,
const fw_fs_posix_cfg_t * cfg )
nodiscard

◆ internal_atomic_noreplace_available()

bool internal_atomic_noreplace_available ( void )
static

Probe whether the host provides an atomic no-replace rename.

Uses deliberately invalid descriptors so support can be detected without touching the filesystem namespace.

Returns
True only when the host recognizes the requested operation.
Return values
trueThe host recognizes an atomic no-replace rename primitive.
falseThe host does not provide the required primitive.
Precondition
No filesystem state is required.
The host syscall ABI matches the platform selected at compile time.
Postcondition
No descriptor or filesystem object is created or consumed.
The result reflects syscall recognition rather than path existence.
Note
The invalid-descriptor probe has no namespace side effects.
Since
0.1.0

Definition at line 78 of file fw_if_fs_posix_bind.c.

References RA8_INTERNAL, and RENAME_NOREPLACE.

Referenced by fw_fs_posix_init().

◆ internal_caps()

void internal_caps ( const fw_fs_posix_state_t * state,
fw_fs_caps_t * out )
static

Assemble capabilities for one initialized POSIX adapter.

Fills fixed workspace sizes, path and handle bounds, and only the optional flags established by configuration or the runtime probe.

Parameters
[in]stateInitialized adapter state and probe results.
[out]outComplete capability description.
Precondition
state and out designate valid objects.
state contains the selected removable-media and atomic probe values.
Postcondition
out describes only guarantees supplied by this adapter and host.
Every workspace size and alignment matches the corresponding state type.
Note
Pure apart from writing the caller-owned output object.
Since
0.1.0

Definition at line 460 of file fw_if_fs_posix_bind.c.

References fw_fs_posix_state_t::atomic_noreplace, fw_fs_caps_t::flags, k_fw_fs_cap_accessed_time, k_fw_fs_cap_atomic_noreplace, k_fw_fs_cap_atomic_replace, k_fw_fs_cap_create_exclusive, k_fw_fs_cap_created_time, k_fw_fs_cap_durable_directory_sync, k_fw_fs_cap_durable_file_sync, k_fw_fs_cap_file_sync, k_fw_fs_cap_modified_time, k_fw_fs_cap_namespace, k_fw_fs_cap_rejects_symlink_walk, k_fw_fs_cap_removable_media, k_fw_fs_cap_same_volume_rename, k_fw_fs_cap_space_query, k_fw_fs_cap_stream, k_fw_fs_cap_symlinks, k_fw_fs_cap_transactions, k_fw_fs_path_cap, k_posix_component_cap, k_posix_max_open_files, RA8_INTERNAL, and fw_fs_posix_state_t::removable_media.

Referenced by fw_fs_posix_init().

◆ internal_root_base_open()

ra8_err_t internal_root_base_open ( const char * path,
const char ** out_cursor,
int * out_fd )
static

Open the descriptor anchor for an absolute or relative root path.

Uses actual / for an absolute path and the process working directory for a relative path. Neither anchor operation traverses any caller-provided component.

Parameters
[in]pathCaller-selected terminated root path.
[out]out_cursorReceives the first byte to scan.
[out]out_fdReceives the owned anchor descriptor.
Returns
Anchor-open status.
Return values
k_ra8_okout_fd owns the selected anchor.
k_ra8_err_invalid_argpath is empty.
k_ra8_err_*Mapped anchor-open failure.
Precondition
path, out_cursor, and out_fd are non-NULL.
path addresses a NUL-terminated string.
Postcondition
Success publishes exactly one owned descriptor and the original cursor.
Failure publishes no descriptor.
Note
Relative paths intentionally use the working directory at call time.
Since
Version 0.1.0

Definition at line 119 of file fw_if_fs_posix_bind.c.

References k_ra8_err_invalid_arg, k_ra8_ok, O_CLOEXEC, O_DIRECTORY, O_NOFOLLOW, and priv_fs_posix_errno().

Referenced by internal_root_open().

◆ internal_root_component_scan()

ra8_err_t internal_root_component_scan ( const char ** cursor,
uint16_t * consumed,
char * out_component,
bool * out_end )
static

Scan one bounded component while normalizing repeated slashes.

Delegates separator skipping and component copying to independently bounded helpers, then reports an end condition for trailing slashes.

Parameters
[in,out]cursorCurrent path byte, advanced past copied content.
[in,out]consumedNumber of path bytes consumed before this call.
[out]out_componentTerminated component destination.
[out]out_endReceives true when no component remains.
Returns
Bounded scan status.
Return values
k_ra8_okOne component or the end condition was produced.
k_ra8_err_invalid_sizeThe path or a component exceeds its bound.
Precondition
All pointer parameters are non-NULL and *cursor is terminated.
out_component has k_posix_component_cap writable bytes.
Postcondition
Success consumes leading slashes and one component if present.
Failure never writes beyond out_component.
Note
Pure apart from caller-owned cursor and output storage.
Since
Version 0.1.0

Definition at line 246 of file fw_if_fs_posix_bind.c.

References internal_root_name_copy(), internal_root_skip_slashes(), k_ra8_ok, and RA8_INTERNAL.

Referenced by internal_root_walk().

◆ internal_root_name_copy()

ra8_err_t internal_root_name_copy ( const char ** cursor,
uint16_t * consumed,
char * out_component )
static

Copy one bounded root component and advance its path cursor.

Copies bytes through the next slash or NUL while enforcing both the per-component capacity and the complete-path capacity. The output remains NUL-terminated on success and bounded failure.

Parameters
[in,out]cursorFirst component byte, advanced to slash or NUL.
[in,out]consumedNumber of path bytes consumed before this call.
[out]out_componentTerminated component destination.
Returns
Bounded component-copy status.
Return values
k_ra8_okOne non-empty terminated component was produced.
k_ra8_err_invalid_sizeThe path or a component exceeds its bound.
Precondition
All pointer parameters are non-NULL and **cursor starts a component.
out_component has k_posix_component_cap writable bytes.
Postcondition
Success advances to the delimiter following the copied component.
Failure never writes beyond out_component.
Note
Pure apart from caller-owned cursor and output storage.
Since
Version 0.1.0

Definition at line 188 of file fw_if_fs_posix_bind.c.

References k_fw_fs_path_cap, k_posix_component_cap, k_ra8_err_invalid_size, k_ra8_ok, and RA8_LOOP_BOUND.

Referenced by internal_root_component_scan().

◆ internal_root_open()

ra8_err_t internal_root_open ( const char * path,
int * out_fd )
static

Open one caller-selected confinement root component by component.

Anchors absolute paths at / and relative paths at ., normalizes repeated and trailing slashes, and accepts native . and .. semantics. Each non-dot component is opened no-follow. Linux rejects every link; Darwin alone permits verified actual-root tmp and var aliases and opens only their canonical components.

Parameters
[in]pathCaller-selected existing host directory.
[out]out_fdReceives the owned confinement-root descriptor.
Returns
Root-open status.
Return values
k_ra8_okout_fd owns the selected directory.
k_ra8_err_access_deniedA symbolic-link component was rejected.
k_ra8_err_invalid_sizeThe complete path or one component is too long.
k_ra8_err_*Mapped open, verification, or descriptor-close failure.
Precondition
path and out_fd are non-NULL.
path is a terminated path naming a caller-selected root.
Postcondition
Success publishes exactly one owned directory descriptor.
Failure publishes no descriptor and follows no symbolic-link pathname.
Note
Thread-safe for independent paths and descriptors.
Since
Version 0.1.0

Definition at line 398 of file fw_if_fs_posix_bind.c.

References internal_root_base_open(), internal_root_walk(), k_ra8_err_invalid_size, k_ra8_ok, priv_fs_posix_close_fd(), and RA8_INTERNAL.

Referenced by fw_fs_posix_init().

◆ internal_root_open_step()

ra8_err_t internal_root_open_step ( int * current,
const char * component )
static

Descend into one root component and retire the previous descriptor.

Opens through priv_fs_posix_component_open, then closes the owned parent. A parent-close failure consumes the newly opened descriptor before returning the close status.

Parameters
[in,out]currentOwned parent descriptor replaced on success.
[in]componentValidated non-dot component.
Returns
Descriptor replacement status.
Return values
k_ra8_okcurrent owns the opened child.
k_ra8_err_*Component-open or descriptor-close failure.
Precondition
current owns an open directory descriptor.
component is non-empty and is not ..
Postcondition
Success consumes the parent and publishes one child descriptor.
An open failure retains the parent for caller cleanup; a parent-close failure consumes both the parent and newly opened child.
Note
Thread-safe for independent descriptors.
Since
Version 0.1.0

Definition at line 282 of file fw_if_fs_posix_bind.c.

References k_ra8_ok, priv_fs_posix_close_fd(), priv_fs_posix_close_fd_preserve(), priv_fs_posix_component_open(), and RA8_INTERNAL.

Referenced by internal_root_walk_step().

◆ internal_root_skip_slashes()

ra8_err_t internal_root_skip_slashes ( const char ** cursor,
uint16_t * consumed )
static

Skip repeated path separators under the complete-path bound.

Advances across each leading slash while counting it against the complete path capacity. Stops before advancing when the next byte would consume the capacity reserved for the terminating NUL.

Parameters
[in,out]cursorCurrent path byte, advanced past copied content.
[in,out]consumedNumber of path bytes consumed before this call.
Returns
Separator-skip status.
Return values
k_ra8_okEvery leading separator was consumed.
k_ra8_err_invalid_sizeThe complete path exceeds its bound.
Precondition
cursor and consumed are non-NULL and *cursor is terminated.
*consumed truthfully counts bytes preceding *cursor.
Postcondition
Success advances to a non-separator byte or the terminator.
Failure advances no farther than the final permitted path byte.
Note
Pure apart from caller-owned cursor state.
Since
Version 0.1.0

Definition at line 154 of file fw_if_fs_posix_bind.c.

References k_fw_fs_path_cap, k_ra8_err_invalid_size, k_ra8_ok, RA8_INTERNAL, and RA8_LOOP_BOUND.

Referenced by internal_root_component_scan().

◆ internal_root_walk()

ra8_err_t internal_root_walk ( const char ** cursor,
uint16_t * consumed,
int * current,
bool * out_complete )
static

Walk every remaining root component beneath an owned anchor.

Repeatedly scans a bounded name, ignores ., and replaces the current descriptor through the shared no-follow component opener.

Parameters
[in,out]cursorCurrent path remainder.
[in,out]consumedNumber of path bytes already consumed.
[in,out]currentOwned directory descriptor advanced by each component.
[out]out_completeReceives true only after reaching path termination.
Returns
Root-walk status.
Return values
k_ra8_okThe terminated root path was fully traversed.
k_ra8_err_*Bounded scanning or component traversal failed.
Precondition
All pointers are non-NULL and current owns an anchor descriptor.
*cursor addresses a terminated root-path remainder.
Postcondition
Success leaves current owning the selected root directory.
Failure leaves at most current for caller cleanup.
Note
Thread-safe for independent descriptors and path storage.
Since
Version 0.1.0

Definition at line 345 of file fw_if_fs_posix_bind.c.

References internal_root_component_scan(), internal_root_walk_step(), k_fw_fs_path_cap, k_posix_component_cap, k_ra8_ok, and RA8_LOOP_BOUND.

Referenced by internal_root_open().

◆ internal_root_walk_step()

ra8_err_t internal_root_walk_step ( int * current,
const char * component )
static

Apply one scanned component to the current root descriptor.

Preserves the current descriptor for the normalized . component; every other component descends through the shared no-follow opener.

Parameters
[in,out]currentOwned directory descriptor advanced when needed.
[in]componentNon-empty terminated component from the bounded scanner.
Returns
Component traversal status.
Return values
k_ra8_okThe dot component was ignored or the child was opened.
k_ra8_err_*Component-open or descriptor-close failure.
Precondition
current owns an open directory descriptor.
component is non-NULL and names one scanned component.
Postcondition
Success leaves current owning the selected directory.
Failure leaves at most current for caller cleanup.
Note
Thread-safe for independent descriptors.
Since
Version 0.1.0

Definition at line 317 of file fw_if_fs_posix_bind.c.

References internal_root_open_step(), k_ra8_ok, RA8_INTERNAL, and strcmp().

Referenced by internal_root_walk().

◆ internal_state_reset()

void internal_state_reset ( fw_fs_posix_state_t * state)
static

Restore one inactive POSIX adapter state to its public sentinel.

Clears all capability inputs and counters in addition to publishing descriptor -1 and an inactive lifecycle flag.

Parameters
[out]stateCaller-owned adapter state to normalize.
Precondition
state is non-NULL and owns no open descriptor.
No interface operation is active against state.
Postcondition
state is inactive with root descriptor -1.
Counters and cached capability inputs are zero or false.
Note
This helper does not close descriptors.
Since
Version 0.1.0

Definition at line 438 of file fw_if_fs_posix_bind.c.

References fw_fs_posix_state_t::atomic_noreplace, fw_fs_posix_state_t::initialized, RA8_INTERNAL, fw_fs_posix_state_t::removable_media, fw_fs_posix_state_t::root_fd, and fw_fs_posix_state_t::transaction_id.

Referenced by fw_fs_posix_deinit(), and fw_fs_posix_init().