|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
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"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. | |
Shared descriptor, raw-directory, and path helpers for the POSIX port.
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.
| #define _GNU_SOURCE |
Request GNU raw-directory syscall declarations on Linux.
Definition at line 26 of file fw_if_fs_posix_common.c.
| #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.
| #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.
|
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.
| [in] | actual | Raw candidate bytes. |
| [in] | expected | Immutable expected bytes. |
| [in] | bytes | Number of positions to compare. |
| true | All bytes positions match. |
| false | At least one compared position differs. |
actual and expected each address at least bytes readable bytes. bytes is less than k_posix_component_cap. bytes. 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().
|
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.
| [in] | fd | Open directory descriptor. |
| [out] | buffer | Destination for raw native records. |
| [in] | capacity | Writable destination capacity. |
| [out] | out_bytes | Receives the accepted byte count including zero EOF. |
| k_ra8_ok | out_bytes contains a count no greater than capacity. |
| k_ra8_err_invalid_state | Reader count or errno contract was violated. |
| k_ra8_err_busy | Every bounded attempt was interrupted. |
| k_ra8_err_* | Mapped non-interrupt reader failure. |
buffer addresses capacity writable bytes. out_bytes addresses one writable uint32_t object. out_bytes. 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().
|
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.
| [in] | ctx | Unused production reader context. |
| [in] | fd | Open directory descriptor. |
| [out] | buffer | Destination for raw native records. |
| [in] | capacity | Writable destination capacity. |
| [out] | out_errno | Receives errno for a negative syscall result, else zero. |
| 0 | Native directory enumeration reached EOF. |
| -1 | The syscall failed or the host layout is unsupported. |
buffer addresses capacity writable bytes. out_errno addresses one writable integer and fd is an owned directory. Definition at line 297 of file fw_if_fs_posix_common.c.
Referenced by internal_directory_read_once().
|
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.
| [in] | fd | Open directory descriptor. |
| [out] | buffer | Destination for raw native records. |
| [in] | capacity | Writable destination capacity. |
| [out] | out_errno | Receives the raw failure errno or zero. |
| 0 | The selected reader reported EOF. |
| -1 | The selected reader reported failure. |
Definition at line 353 of file fw_if_fs_posix_common.c.
References internal_directory_read_native().
Referenced by internal_directory_fill().
|
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.
| [out] | out | Six-byte hexadecimal field. |
| [in] | value | Transaction identifier whose low 24 bits are rendered. |
out addresses k_posix_stage_hex_digits writable bytes. 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().
| 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.
| [in,out] | fd | Owned descriptor slot, invalidated before the close. |
| k_ra8_ok | The 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. |
fd addresses one writable integer this port owns; the pointer is dereferenced without a null guard. fd. 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().
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.
| [in,out] | fd | Owned descriptor slot, invalidated by the close attempt. |
| [in] | primary | Status produced before descriptor cleanup. |
primary when it is not k_ra8_ok; otherwise the close status. | k_ra8_ok | The primary operation and descriptor close both succeeded. |
| k_ra8_err_* | The primary operation failed, or cleanup failed after a successful primary operation. |
fd is non-NULL and addresses one writable descriptor slot. 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().
| 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.
| [out] | out | Destination holding k_fw_fs_path_cap writable bytes. |
| [in] | path | Source path to copy, including its terminator. |
| k_ra8_ok | out holds the terminated copy. |
| k_ra8_err_invalid_size | No terminator appears within the capacity. |
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. out NUL-terminated with at most k_fw_fs_path_cap - 1 visible bytes. out fully overwritten and unterminated, so a rejected copy must never be read back as a string. 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().
| 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.
| [in] | fd | Open directory descriptor owning the enumeration position. |
| [in,out] | reader | Caller-owned batch buffer and cursor. |
| [out] | out | Borrowed name view and exact record extent. |
| [out] | out_end | True when the host reported end of directory. |
| k_ra8_ok | out describes one record, or out_end is true at end. |
| k_ra8_err_null_ptr | reader, out, or out_end is NULL. |
| k_ra8_err_invalid_state | fd is negative, the cursor and valid extent disagree, or a native record layout is malformed. |
| k_ra8_err_invalid_size | A record name exceeds k_posix_component_cap. |
| k_ra8_err_busy | Every bounded refill attempt was interrupted. |
| k_ra8_err_* | Mapped raw-read failure. |
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. reader and stays valid only until the next call made on the same reader. 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().
| 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.
| [in] | value | Captured errno value, or zero for an observed success. |
value. | k_ra8_ok | value is zero. |
| k_ra8_err_not_found | ENOENT or ENOTDIR. |
| k_ra8_err_exists | EEXIST. |
| k_ra8_err_no_mem | ENOSPC, EDQUOT, EMFILE, or ENFILE. |
| k_ra8_err_not_empty | ENOTEMPTY. |
| k_ra8_err_access_denied | EACCES, EPERM, or ELOOP. |
| k_ra8_err_invalid_arg | EINVAL, EXDEV, ENAMETOOLONG, or EISDIR. |
| k_ra8_err_invalid_size | EFBIG or EOVERFLOW. |
| k_ra8_err_invalid_state | EBADF. |
| k_ra8_err_busy | EBUSY. |
| k_ra8_err_not_supported | ENOTSUP where the host defines it. |
| k_ra8_fail | Every other errno value. |
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. 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().
| 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.
| [in,out] | ctx | Initialized confined-root adapter context. |
| [in] | path | Validated portable directory path. |
| [in] | max_entries | Maximum portable callback deliveries. |
| [in] | callback | Portable directory-entry callback. |
| [in,out] | callback_ctx | Opaque callback state. |
| [in,out] | out_count | Running count initialized by public dispatch. |
| [out] | out_complete | Whether native EOF was observed. |
| k_ra8_ok | Enumeration ended without an error. |
| k_ra8_err_* | First confined directory, callback, stat, or close failure. |
out_count initially contains zero. max_entries. 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.
| 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.
| [in] | component | Terminated candidate alias basename. |
| [in] | target | Raw, not necessarily terminated link-target bytes. |
| [in] | target_bytes | Number of readable bytes in target. |
| [out] | out_alias | Receives the classified alias selection. |
| k_ra8_ok | The component and target are one approved pair. |
| k_ra8_err_access_denied | The pair is not approved. |
component, target, and out_alias are non-NULL. target addresses at least target_bytes readable bytes. out_alias set to k_posix_root_alias_none. 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().
| 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.
| [in] | root_fd | Open descriptor for a root-like directory. |
| [in] | alias | Valid non-none alias selection. |
| [out] | out_fd | Receives the owned canonical directory descriptor. |
| k_ra8_ok | out_fd owns the selected canonical directory. |
| k_ra8_err_invalid_arg | alias is not a supported selection. |
| k_ra8_err_* | Mapped canonical open or descriptor-close failure. |
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. out_fd. root_fd identifies actual / through ::priv_fs_posix_root_alias_verify. 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().
| 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.
| [in] | destination | Validated portable destination path. |
| [in] | id | Transaction identifier; only its low 24 bits are rendered. |
| [out] | out | Destination holding k_fw_fs_path_cap writable bytes. |
| k_ra8_ok | out holds the terminated sibling stage path. |
| k_ra8_err_invalid_size | destination has no terminator within k_fw_fs_path_cap, or its parent prefix leaves no room for the leaf. |
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. destination's parent directory, so the later publication rename never crosses a filesystem. out untouched. 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().
| 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.
| [in] | seconds | POSIX UTC epoch seconds taken from one struct timespec. |
| [in] | nanoseconds | Subsecond field of that same struct timespec, in 0..k_posix_nanosecond_max. |
| valid==true | Every civil field and the subsecond are populated in UTC. |
| valid==false | nanoseconds is out of range, gmtime_r failed, or the civil year does not fit the portable field; the value stays zeroed. |
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. 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().