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

Shared descriptor, raw-directory, and path helpers for the POSIX port. More...

#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "ra8_attributes.h"
#include "fw_if_fs_posix_internal.h"
#include "ra8_err.h"
Include dependency graph for fw_if_fs_posix_common.c:

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 Request GNU raw-directory 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.

Functions

ra8_err_t priv_fs_posix_errno (int value)
 Map one captured errno value into ra8_err_t.
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.
static bool internal_bytes_equal (const char *actual, const char *expected, size_t bytes)
 Compare one bounded raw byte span with an expected byte sequence.
ra8_err_t priv_fs_posix_root_alias_classify (const char *component, const char *target, size_t target_bytes, posix_root_alias_t *out_alias)
 Classify one exact filesystem-root alias component and target pair.
ra8_err_t priv_fs_posix_root_alias_open (int root_fd, posix_root_alias_t alias, int *out_fd)
 Open a classified root alias through its canonical components.
static int64_t internal_directory_read_native (void *ctx, int fd, uint8_t *buffer, uint32_t capacity, int *out_errno)
 Read one raw directory batch without C-runtime stream state.
static int64_t internal_directory_read_once (int fd, uint8_t *buffer, uint32_t capacity, int *out_errno)
 Dispatch one raw read through the production or test-only reader.
static ra8_err_t internal_directory_fill (int fd, uint8_t *buffer, uint32_t capacity, uint32_t *out_bytes)
 Retry a bounded number of interrupted raw directory reads.
ra8_err_t priv_fs_posix_directory_next (int fd, posix_directory_reader_t *reader, posix_directory_record_t *out, bool *out_end)
 Read and validate the next raw hosted directory record.
fw_fs_timestamp_t priv_fs_posix_timestamp (time_t seconds, long nanoseconds)
 Convert a POSIX UTC instant into the portable civil representation.
ra8_err_t priv_fs_posix_copy_path (char *out, const char *path)
 Copy one bounded portable path.
static void internal_hex6 (char out[k_posix_stage_hex_digits], uint32_t value)
 Render the bounded six-digit transaction suffix.
ra8_err_t priv_fs_posix_stage_path (const char *destination, uint32_t id, char *out)
 Build an 8.3-compatible sibling transaction path.
ra8_err_t priv_fs_posix_listdir (void *ctx, const char *path, uint32_t max_entries, fw_fs_list_fn_t callback, void *callback_ctx, uint32_t *out_count, bool *out_complete)
 Enumerate a POSIX directory through bounded raw records.

Detailed Description

Shared descriptor, raw-directory, and path helpers for the POSIX port.

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

Centralizes errno mapping, descriptor invalidation, platform-neutral alias classification and canonical opening, Darwin actual-root verification, bounded raw directory record decoding, civil timestamp conversion, path copying, and sibling stage-name construction. Keeping these operations shared gives every backend path the same failure vocabulary and close-once behavior.

Definition in file fw_if_fs_posix_common.c.

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Request GNU raw-directory syscall declarations on Linux.

Definition at line 26 of file fw_if_fs_posix_common.c.

◆ O_CLOEXEC

#define O_CLOEXEC   (0)

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

Definition at line 48 of file fw_if_fs_posix_common.c.

◆ O_NOFOLLOW

#define O_NOFOLLOW   (0)

Zero fallback paired with explicit no-follow metadata validation.

Definition at line 53 of file fw_if_fs_posix_common.c.

Function Documentation

◆ internal_bytes_equal()

bool internal_bytes_equal ( const char * actual,
const char * expected,
size_t bytes )
static

Compare one bounded raw byte span with an expected byte sequence.

Examines exactly bytes positions without requiring either span to carry a terminator. The caller supplies the independently validated extent used by the root-alias classifier.

Parameters
[in]actualRaw candidate bytes.
[in]expectedImmutable expected bytes.
[in]bytesNumber of positions to compare.
Returns
Whether every compared byte is equal.
Return values
trueAll bytes positions match.
falseAt least one compared position differs.
Precondition
actual and expected each address at least bytes readable bytes.
bytes is less than k_posix_component_cap.
Postcondition
Neither input span is modified.
The function reads no position at or beyond bytes.
Note
Pure and thread-safe.
Since
Version 0.1.0

Definition at line 136 of file fw_if_fs_posix_common.c.

References k_posix_component_cap, and RA8_LOOP_BOUND.

Referenced by priv_fs_posix_root_alias_classify().

◆ internal_directory_fill()

ra8_err_t internal_directory_fill ( int fd,
uint8_t * buffer,
uint32_t capacity,
uint32_t * out_bytes )
static

Retry a bounded number of interrupted raw directory reads.

Accepts bounded non-negative byte counts, retries only EINTR, maps other errno values, and stops after a fixed interrupt budget.

Parameters
[in]fdOpen directory descriptor.
[out]bufferDestination for raw native records.
[in]capacityWritable destination capacity.
[out]out_bytesReceives the accepted byte count including zero EOF.
Returns
Bounded raw-read status.
Return values
k_ra8_okout_bytes contains a count no greater than capacity.
k_ra8_err_invalid_stateReader count or errno contract was violated.
k_ra8_err_busyEvery bounded attempt was interrupted.
k_ra8_err_*Mapped non-interrupt reader failure.
Precondition
buffer addresses capacity writable bytes.
out_bytes addresses one writable uint32_t object.
Postcondition
Success initializes out_bytes.
The retry count never exceeds k_posix_directory_read_retries.
Note
Not thread-safe for concurrent use of one directory descriptor offset.
Since
Version 0.1.0

Definition at line 385 of file fw_if_fs_posix_common.c.

References internal_directory_read_once(), k_posix_directory_read_retries, k_ra8_err_busy, k_ra8_err_invalid_state, k_ra8_ok, and priv_fs_posix_errno().

Referenced by priv_fs_posix_directory_next().

◆ internal_directory_read_native()

int64_t internal_directory_read_native ( void * ctx,
int fd,
uint8_t * buffer,
uint32_t capacity,
int * out_errno )
static

Read one raw directory batch without C-runtime stream state.

Invokes the platform descriptor syscall directly and reports errno separately so the bounded retry layer can distinguish interrupts.

Parameters
[in]ctxUnused production reader context.
[in]fdOpen directory descriptor.
[out]bufferDestination for raw native records.
[in]capacityWritable destination capacity.
[out]out_errnoReceives errno for a negative syscall result, else zero.
Returns
Raw syscall byte count, zero at EOF, or a negative failure result.
Return values
0Native directory enumeration reached EOF.
-1The syscall failed or the host layout is unsupported.
Precondition
buffer addresses capacity writable bytes.
out_errno addresses one writable integer and fd is an owned directory.
Postcondition
A non-negative result never claims more than the host syscall wrote.
Filesystem contents and descriptor ownership are unchanged.
Note
Not thread-safe for concurrent reads using one directory descriptor offset.
Since
Version 0.1.0

Definition at line 297 of file fw_if_fs_posix_common.c.

Referenced by internal_directory_read_once().

◆ internal_directory_read_once()

int64_t internal_directory_read_once ( int fd,
uint8_t * buffer,
uint32_t capacity,
int * out_errno )
static

Dispatch one raw read through the production or test-only reader.

Selects the injected fault-vector reader in test builds, otherwise calls the exact production raw-syscall adapter.

Parameters
[in]fdOpen directory descriptor.
[out]bufferDestination for raw native records.
[in]capacityWritable destination capacity.
[out]out_errnoReceives the raw failure errno or zero.
Returns
Selected reader's signed byte-count result.
Return values
0The selected reader reported EOF.
-1The selected reader reported failure.
Precondition
Buffer and errno outputs satisfy internal_directory_read_native.
Any installed test callback and context remain valid for the call.
Postcondition
Exactly one selected reader is invoked.
Production builds cannot dispatch through test-only global state.
Note
Test injection is not thread-safe; production follows descriptor semantics.
Since
Version 0.1.0

Definition at line 353 of file fw_if_fs_posix_common.c.

References internal_directory_read_native().

Referenced by internal_directory_fill().

◆ internal_hex6()

void internal_hex6 ( char out[k_posix_stage_hex_digits],
uint32_t value )
static

Render the bounded six-digit transaction suffix.

Emits lowercase nibbles from most to least significant without a NUL; the caller inserts the exact field into a bounded stage leaf.

Parameters
[out]outSix-byte hexadecimal field.
[in]valueTransaction identifier whose low 24 bits are rendered.
Precondition
out addresses k_posix_stage_hex_digits writable bytes.
The destination does not overlap read-only digit storage.
Postcondition
Exactly six lowercase hexadecimal characters are written.
Bytes outside the six-byte field are unchanged.
Note
Pure apart from caller output and thread-safe.
Since
Version 0.1.0

Definition at line 631 of file fw_if_fs_posix_common.c.

References k_posix_hex_last_digit, k_posix_hex_nibble_bits, k_posix_hex_nibble_mask, k_posix_stage_hex_digits, and RA8_INTERNAL.

Referenced by priv_fs_posix_stage_path().

◆ priv_fs_posix_close_fd()

ra8_err_t priv_fs_posix_close_fd ( int * fd)

Close exactly once and invalidate the caller's descriptor.

Reads *fd, stores -1 back, and only then calls close, so a caller that retries after a failure cannot close a descriptor number the host has already recycled for another object. An already-invalidated slot is reported rather than closed, which is what makes the unconditional cleanup calls on every error path in this port safe.

Parameters
[in,out]fdOwned descriptor slot, invalidated before the close.
Returns
Mapped descriptor-close status.
Return values
k_ra8_okThe descriptor closed successfully.
k_ra8_err_invalid_state*fd was already negative; nothing was closed.
k_ra8_err_*Mapped close failure from priv_fs_posix_errno.
Precondition
fd addresses one writable integer this port owns; the pointer is dereferenced without a null guard.
No other owner closes or reuses *fd concurrently; the invalidation protects only against a repeated call made through fd.
Postcondition
*fd is -1 on every return path, including both failure paths.
close is issued at most once, and never for an already-invalid slot.
Note
Not thread-safe for concurrent access to one descriptor slot.
Since
Version 0.1.0

Definition at line 98 of file fw_if_fs_posix_common.c.

References k_ra8_err_invalid_state, k_ra8_ok, priv_fs_posix_errno(), and RA8_PRIV.

Referenced by fw_fs_posix_deinit(), internal_directory_open(), internal_mkdir(), internal_native_stat(), internal_parent_open_step(), internal_parent_sync(), internal_rename(), internal_rmdir(), internal_root_open(), internal_root_open_step(), internal_unlink(), priv_fs_posix_close(), priv_fs_posix_close_fd_preserve(), priv_fs_posix_dir_close(), priv_fs_posix_open(), and priv_fs_posix_root_alias_open().

◆ priv_fs_posix_close_fd_preserve()

ra8_err_t priv_fs_posix_close_fd_preserve ( int * fd,
ra8_err_t primary )

Close one owned descriptor while preserving a primary status.

Delegates descriptor consumption to priv_fs_posix_close_fd. When primary already reports a failure, that failure remains the caller-visible result even if cleanup also fails. When the primary operation succeeded, the descriptor-close result is returned so a cleanup failure cannot be hidden.

Parameters
[in,out]fdOwned descriptor slot, invalidated by the close attempt.
[in]primaryStatus produced before descriptor cleanup.
Returns
primary when it is not k_ra8_ok; otherwise the close status.
Return values
k_ra8_okThe primary operation and descriptor close both succeeded.
k_ra8_err_*The primary operation failed, or cleanup failed after a successful primary operation.
Precondition
fd is non-NULL and addresses one writable descriptor slot.
*fd satisfies the ownership contract of priv_fs_posix_close_fd.
Postcondition
*fd is -1 and the descriptor was closed at most once.
A primary failure is never replaced by a secondary cleanup failure.
Note
Not thread-safe for concurrent access to one descriptor slot.
Since
Version 0.1.0

Definition at line 111 of file fw_if_fs_posix_common.c.

References k_ra8_ok, priv_fs_posix_close_fd(), and RA8_PRIV.

Referenced by internal_directory_open(), internal_parent_open_step(), internal_root_open_step(), priv_fs_posix_open(), priv_fs_posix_parent_open(), and priv_fs_posix_root_alias_open().

◆ priv_fs_posix_copy_path()

ra8_err_t priv_fs_posix_copy_path ( char * out,
const char * path )

Copy one bounded portable path.

Copies bytes forward until the terminator is reached or the portable path capacity is exhausted, so an oversized or unterminated source is reported instead of overrunning out. The bound is the portable k_fw_fs_path_cap rather than a host PATH_MAX, which keeps every adapter path the same size as the caller workspace that stores it.

Parameters
[out]outDestination holding k_fw_fs_path_cap writable bytes.
[in]pathSource path to copy, including its terminator.
Returns
Bounded path-copy status.
Return values
k_ra8_okout holds the terminated copy.
k_ra8_err_invalid_sizeNo terminator appears within the capacity.
Precondition
out addresses k_fw_fs_path_cap writable bytes and does not overlap path; both pointers are dereferenced without a null guard.
path stays readable through its terminator, or for k_fw_fs_path_cap bytes when it carries none.
Postcondition
Success leaves out NUL-terminated with at most k_fw_fs_path_cap - 1 visible bytes.
Failure leaves out fully overwritten and unterminated, so a rejected copy must never be read back as a string.
Note
Pure apart from the caller's destination, and thread-safe.
Since
Version 0.1.0

Definition at line 607 of file fw_if_fs_posix_common.c.

References k_fw_fs_path_cap, k_ra8_err_invalid_size, k_ra8_ok, and RA8_PRIV.

Referenced by internal_txn_begin().

◆ priv_fs_posix_directory_next()

ra8_err_t priv_fs_posix_directory_next ( int fd,
posix_directory_reader_t * reader,
posix_directory_record_t * out,
bool * out_end )

Read and validate the next raw hosted directory record.

Serves the next record from reader's fixed buffer and refills that buffer with one bounded raw syscall batch when the cursor reaches the end of the previous batch, so enumeration needs no allocator-backed DIR object. Both the caller-supplied cursor state and every decoded record extent are re-validated on entry, and the published name borrows bytes inside reader instead of being copied. Dot entries are not filtered here; the portable layer above does that.

Parameters
[in]fdOpen directory descriptor owning the enumeration position.
[in,out]readerCaller-owned batch buffer and cursor.
[out]outBorrowed name view and exact record extent.
[out]out_endTrue when the host reported end of directory.
Returns
Raw record read, decode, or cursor-validation status.
Return values
k_ra8_okout describes one record, or out_end is true at end.
k_ra8_err_null_ptrreader, out, or out_end is NULL.
k_ra8_err_invalid_statefd is negative, the cursor and valid extent disagree, or a native record layout is malformed.
k_ra8_err_invalid_sizeA record name exceeds k_posix_component_cap.
k_ra8_err_busyEvery bounded refill attempt was interrupted.
k_ra8_err_*Mapped raw-read failure.
Precondition
fd is the same descriptor that produced reader's current batch; pairing a cursor with another descriptor interleaves two enumerations.
reader was zero-initialized before the first call of an enumeration and is not shared with a second cursor.
Postcondition
Success advances the cursor by exactly the decoded record extent, so no record is delivered twice.
out->name points inside reader and stays valid only until the next call made on the same reader.
Note
Not thread-safe for concurrent use of one descriptor offset or reader.
Since
Version 0.1.0

Definition at line 526 of file fw_if_fs_posix_common.c.

References posix_directory_reader_t::buffer, posix_directory_reader_t::cursor, internal_directory_fill(), k_ra8_err_invalid_state, k_ra8_err_null_ptr, k_ra8_ok, RA8_PRIV, posix_directory_record_t::record_bytes, and posix_directory_reader_t::valid_bytes.

Referenced by priv_fs_posix_dir_next().

◆ priv_fs_posix_errno()

ra8_err_t priv_fs_posix_errno ( int value)

Map one captured errno value into ra8_err_t.

Translates the host failure vocabulary into the portable one with a total switch, so every backend path in this port reports the same code for the same condition. Families collapse deliberately: descriptor and space exhaustion both read as k_ra8_err_no_mem, and ELOOP joins the permission family because an unapproved symbolic link is denied rather than missing. Any value the switch does not name becomes k_ra8_fail, never a success code.

Parameters
[in]valueCaptured errno value, or zero for an observed success.
Returns
Portable status for value.
Return values
k_ra8_okvalue is zero.
k_ra8_err_not_foundENOENT or ENOTDIR.
k_ra8_err_existsEEXIST.
k_ra8_err_no_memENOSPC, EDQUOT, EMFILE, or ENFILE.
k_ra8_err_not_emptyENOTEMPTY.
k_ra8_err_access_deniedEACCES, EPERM, or ELOOP.
k_ra8_err_invalid_argEINVAL, EXDEV, ENAMETOOLONG, or EISDIR.
k_ra8_err_invalid_sizeEFBIG or EOVERFLOW.
k_ra8_err_invalid_stateEBADF.
k_ra8_err_busyEBUSY.
k_ra8_err_not_supportedENOTSUP where the host defines it.
k_ra8_failEvery other errno value.
Precondition
value was captured immediately after the failing host call; an intervening close or stat may already have overwritten errno.
value is an errno code, never a negated syscall return, because a zero argument is reported as success.
Postcondition
No caller object, errno, or host state is read or written.
An unrecognized value collapses to k_ra8_fail, so no host failure can be mapped onto a success code.
Note
Pure and thread-safe.
Since
Version 0.1.0

Definition at line 56 of file fw_if_fs_posix_common.c.

References k_ra8_err_access_denied, k_ra8_err_busy, k_ra8_err_exists, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_err_invalid_state, k_ra8_err_no_mem, k_ra8_err_not_empty, k_ra8_err_not_found, k_ra8_err_not_supported, k_ra8_fail, k_ra8_ok, and RA8_PRIV.

Referenced by internal_directory_fill(), internal_directory_open(), internal_intermediate_check(), internal_mkdir(), internal_native_stat(), internal_parent_sync(), internal_read(), internal_rename_noreplace(), internal_rename_opened(), internal_rmdir(), internal_root_base_open(), internal_space(), internal_tell(), internal_unlink(), priv_fs_posix_close_fd(), priv_fs_posix_component_open(), priv_fs_posix_dir_next(), priv_fs_posix_open(), priv_fs_posix_parent_open(), priv_fs_posix_root_alias_open(), priv_fs_posix_seek(), priv_fs_posix_size(), priv_fs_posix_sync(), and priv_fs_posix_write().

◆ priv_fs_posix_listdir()

ra8_err_t priv_fs_posix_listdir ( void * ctx,
const char * path,
uint32_t max_entries,
fw_fs_list_fn_t callback,
void * callback_ctx,
uint32_t * out_count,
bool * out_complete )

Enumerate a POSIX directory through bounded raw records.

Opens without symlink traversal, skips dot entries, bounds native records plus look-ahead, stats each leaf no-follow, and closes always.

Parameters
[in,out]ctxInitialized confined-root adapter context.
[in]pathValidated portable directory path.
[in]max_entriesMaximum portable callback deliveries.
[in]callbackPortable directory-entry callback.
[in,out]callback_ctxOpaque callback state.
[in,out]out_countRunning count initialized by public dispatch.
[out]out_completeWhether native EOF was observed.
Returns
Enumeration, callback, metadata, or close status.
Return values
k_ra8_okEnumeration ended without an error.
k_ra8_err_*First confined directory, callback, stat, or close failure.
Precondition
Pointer arguments are non-NULL and public bounds were validated.
out_count initially contains zero.
Postcondition
Callback delivery never exceeds max_entries.
The directory descriptor is closed on every return path.
Note
Not thread-safe with concurrent mutation of the enumerated directory.
Since
Version 0.1.0

Definition at line 676 of file fw_if_fs_posix_common.c.

References k_ra8_ok, fw_fs_dirent_value_t::name, fw_fs_dirent_value_t::name_bytes, priv_fs_posix_dir_close(), priv_fs_posix_dir_next(), priv_fs_posix_dir_open(), RA8_PRIV, fw_fs_dirent_value_t::size_bytes, and fw_fs_dirent_value_t::type.

◆ priv_fs_posix_root_alias_classify()

ra8_err_t priv_fs_posix_root_alias_classify ( const char * component,
const char * target,
size_t target_bytes,
posix_root_alias_t * out_alias )

Classify one exact filesystem-root alias component and target pair.

Accepts only the byte-exact relative pairs tmp -> private/tmp and var -> private/var. Absolute targets, swapped components, prefixes, suffixes, truncation, and every other pair remain denied.

Parameters
[in]componentTerminated candidate alias basename.
[in]targetRaw, not necessarily terminated link-target bytes.
[in]target_bytesNumber of readable bytes in target.
[out]out_aliasReceives the classified alias selection.
Returns
Root-alias tuple classification status.
Return values
k_ra8_okThe component and target are one approved pair.
k_ra8_err_access_deniedThe pair is not approved.
Precondition
component, target, and out_alias are non-NULL.
target addresses at least target_bytes readable bytes.
Postcondition
Success publishes the pair's non-none alias selection.
Failure leaves out_alias set to k_posix_root_alias_none.
Note
Pure and thread-safe.
Since
Version 0.1.0

Definition at line 149 of file fw_if_fs_posix_common.c.

References internal_bytes_equal(), k_posix_root_alias_none, k_posix_root_alias_tmp, k_posix_root_alias_var, k_ra8_err_access_denied, k_ra8_ok, RA8_PRIV, and strcmp().

◆ priv_fs_posix_root_alias_open()

ra8_err_t priv_fs_posix_root_alias_open ( int root_fd,
posix_root_alias_t alias,
int * out_fd )

Open a classified root alias through its canonical components.

Opens private beneath root_fd, then the selected tmp or var child, applying O_NOFOLLOW to both operations. The original alias path is never opened, closing the validation-to-use replacement window.

Parameters
[in]root_fdOpen descriptor for a root-like directory.
[in]aliasValid non-none alias selection.
[out]out_fdReceives the owned canonical directory descriptor.
Returns
Canonical directory-open status.
Return values
k_ra8_okout_fd owns the selected canonical directory.
k_ra8_err_invalid_argalias is not a supported selection.
k_ra8_err_*Mapped canonical open or descriptor-close failure.
Precondition
root_fd remains open and contains real private/tmp or private/var directories corresponding to alias.
alias is k_posix_root_alias_tmp or k_posix_root_alias_var.
out_fd addresses one writable integer descriptor object.
Postcondition
Success publishes exactly one owned descriptor in out_fd.
Failure publishes no descriptor and closes every descriptor opened here.
Warning
Darwin production callers must first prove root_fd identifies actual / through ::priv_fs_posix_root_alias_verify.
Note
Fixture tests may exercise the canonical no-follow mechanics beneath a private root-like directory without weakening the production rule.
Thread-safe for independent descriptors.
Since
Version 0.1.0

Definition at line 211 of file fw_if_fs_posix_common.c.

References k_posix_root_alias_tmp, k_posix_root_alias_var, k_ra8_err_invalid_arg, k_ra8_ok, O_CLOEXEC, O_DIRECTORY, O_NOFOLLOW, priv_fs_posix_close_fd(), priv_fs_posix_close_fd_preserve(), priv_fs_posix_errno(), and RA8_PRIV.

Referenced by priv_fs_posix_component_open().

◆ priv_fs_posix_stage_path()

ra8_err_t priv_fs_posix_stage_path ( const char * destination,
uint32_t id,
char * out )

Build an 8.3-compatible sibling transaction path.

Retains everything through destination's final / and appends the fixed twelve-byte leaf TX, six lowercase hexadecimal digits of id's low 24 bits, and .TMP. Staging beside the destination rather than in a scratch directory is what lets publication be one rename inside a single directory and filesystem. Uniqueness belongs to the caller, which advances its transaction counter and retries when the constructed leaf already exists.

Parameters
[in]destinationValidated portable destination path.
[in]idTransaction identifier; only its low 24 bits are rendered.
[out]outDestination holding k_fw_fs_path_cap writable bytes.
Returns
Stage-name construction status.
Return values
k_ra8_okout holds the terminated sibling stage path.
k_ra8_err_invalid_sizedestination has no terminator within k_fw_fs_path_cap, or its parent prefix leaves no room for the leaf.
Precondition
destination is a validated portable path beginning with /, so the retained prefix ends at a real separator.
out addresses k_fw_fs_path_cap writable bytes and does not overlap destination.
Postcondition
Success publishes a path sharing destination's parent directory, so the later publication rename never crosses a filesystem.
Both capacity checks precede every write, so a rejected call leaves out untouched.
Note
Pure apart from the caller's destination, and thread-safe; the helper contributes no uniqueness of its own.
Since
Version 0.1.0

Definition at line 641 of file fw_if_fs_posix_common.c.

References internal_hex6(), k_fw_fs_path_cap, k_posix_stage_hex_digits, k_posix_stage_leaf_span, k_posix_transaction_id_mask, k_ra8_err_invalid_size, k_ra8_ok, and RA8_PRIV.

Referenced by internal_stage_open().

◆ priv_fs_posix_timestamp()

fw_fs_timestamp_t priv_fs_posix_timestamp ( time_t seconds,
long nanoseconds )

Convert a POSIX UTC instant into the portable civil representation.

Rejects an out-of-range subsecond, converts seconds with the reentrant gmtime_r, and rejects a civil year that does not fit the portable uint16_t field. Rejection is total rather than partial: the zero-initialized value is returned unmodified, so valid is the one flag a caller has to test. No zone conversion is applied.

Parameters
[in]secondsPOSIX UTC epoch seconds taken from one struct timespec.
[in]nanosecondsSubsecond field of that same struct timespec, in 0..k_posix_nanosecond_max.
Returns
Portable civil timestamp value.
Return values
valid==trueEvery civil field and the subsecond are populated in UTC.
valid==falsenanoseconds is out of range, gmtime_r failed, or the civil year does not fit the portable field; the value stays zeroed.
Precondition
seconds is a UTC epoch instant rather than a local-time value, because the published utc_offset_min is hard-coded to zero.
nanoseconds is the timespec subsecond, not a total nanosecond count, because it is published beside the separately converted seconds.
Postcondition
Success sets both valid and utc_offset_valid with a zero utc_offset_min, so the value always reads as UTC.
Rejection returns a fully zeroed value rather than a partly filled one.
Note
Pure and thread-safe; the conversion uses the reentrant gmtime_r.
Since
Version 0.1.0

Definition at line 574 of file fw_if_fs_posix_common.c.

References fw_fs_datetime_t::day, fw_fs_datetime_t::hour, k_posix_epoch_year_offset, k_posix_nanosecond_max, fw_fs_datetime_t::minute, fw_fs_datetime_t::month, fw_fs_datetime_t::nanosecond, RA8_PRIV, fw_fs_datetime_t::second, fw_fs_datetime_t::utc_offset_min, fw_fs_timestamp_t::utc_offset_valid, fw_fs_timestamp_t::valid, fw_fs_timestamp_t::value, and fw_fs_datetime_t::year.

Referenced by internal_stat().