11#define _POSIX_C_SOURCE (200809L)
27typedef enum : uint32_t {
52 const size_t len = (path ==
nullptr) ? 0U :
strlen(path);
56 const char* slash =
strrchr(path,
'/');
58 const char* text =
".";
59 if (slash !=
nullptr) {
61 take = (slash == path) ? 1U : (size_t)(slash - path);
63 (void)
memcpy(parent, text, take);
90 reverse[count++] = (char)(
'0' + (
char)(value %
k_spool_radix));
92 }
while (value != 0U);
97 name[(*len)++] = reverse[--count];
121 static const char prefix[] =
".ra8spool.";
122 size_t len =
sizeof(prefix) - 1U;
123 (void)
memcpy(name, prefix, len);
155 if ((state ==
nullptr) || (state->
fd < 0) || state->
sealed ||
156 ((bytes ==
nullptr) && (len != 0U)) || ((uint64_t)len > (UINT64_MAX - state->
position))) {
161 const ssize_t rc = pwrite(state->
fd, &bytes[done], len - done, (off_t)(state->
position + done));
164 }
else if ((rc < 0) && (errno == EINTR)) {
194 if ((state ==
nullptr) || (state->
fd < 0) || state->
sealed) {
197 struct stat status = {};
198 if ((state->
position != expected_size) || (fstat(state->
fd, &status) != 0) ||
199 ((uint64_t)status.st_size != expected_size)) {
202 if (fsync(state->
fd) != 0) {
232 if ((state ==
nullptr) || (got ==
nullptr) || (state->
fd < 0) || !state->
sealed ||
233 ((bytes ==
nullptr) && (len != 0U))) {
237 if ((offset >= state->
position) || (len == 0U)) {
240 const uint64_t remain = state->
position - offset;
241 if ((uint64_t)len > remain) {
242 len = (size_t)remain;
245 const ssize_t rc = pread(state->
fd, &bytes[*got], len - *got, (off_t)(offset + *got));
248 }
else if (rc == 0) {
250 }
else if (errno != EINTR) {
282 state->
fd = openat(parent_fd,
286 if (state->
fd >= 0) {
287 if (unlinkat(parent_fd, name, 0) == 0) {
290 (void)close(state->
fd);
292 (void)unlinkat(parent_fd, name, 0);
295 if (errno != EEXIST) {
306 if ((anchor_path ==
nullptr) || (state ==
nullptr) || (out ==
nullptr)) {
321 (void)close(parent_fd);
335 if ((state !=
nullptr) && (state->
fd >= 0)) {
336 (void)close(state->
fd);
static uint32_t internal_read(void)
Read current GPT counter ticks, or return UINT32_MAX on err.
#define O_DIRECTORY
No-op directory-open fallback for hosts lacking the flag.
#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.
static ra8_err_t internal_read(void *ctx, void *file_state, uint8_t *dst, uint32_t cap, uint32_t *out_read)
Annotation-attribute framework macros for ra8-firmware.
#define RA8_PRIV
Module-private helper: shared across TUs but only inside one library.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_fail
Generic unspecified failure.
@ k_ra8_err_exists
Item already exists – cannot create again.
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
@ k_ra8_err_validation_failed
Validation rule failed (caller-supplied invariant not satisfied).
@ 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.
Raw file-descriptor adapters for the portable format-tool contracts.
@ k_ra8_fmt_host_path_cap
Parent-path storage including NUL.
@ k_ra8_fmt_host_name_cap
One leaf name including NUL.
static ra8_err_t internal_append(void *ctx, const uint8_t *bytes, size_t len)
Append exactly to one unsealed anonymous descriptor.
static ra8_err_t internal_parent(const char *path, char parent[k_ra8_fmt_host_path_cap])
Copy the anchor parent into fixed storage.
static ra8_err_t internal_seal(void *ctx, uint64_t expected_size)
Seal an exact spool extent before positioned reads.
static ra8_err_t internal_create(int parent_fd, ra8_fmt_host_spool_t *state)
Create and immediately unlink one exclusive scratch leaf.
spool_const_t
Scratch creation and spelling bounds.
@ k_spool_attempts
Exclusive-create collision ceiling.
@ k_spool_radix
Decimal filename radix.
@ k_spool_digits
Digits in one uint64_t spelling.
@ k_spool_mode
Owner-only scratch permissions.
void priv_fmt_host_spool_close(ra8_fmt_host_spool_t *state)
Close an anonymous scratch artifact.
ra8_err_t priv_fmt_host_spool_open(const char *anchor_path, ra8_fmt_host_spool_t *state, ra8_fmt_spool_t *out)
Create an anonymous scratch file beside an anchored input path.
static ra8_err_t internal_decimal(char name[k_ra8_fmt_host_name_cap], size_t *len, uint64_t value)
Append one unsigned decimal into a bounded scratch name.
static ra8_err_t internal_name(uint32_t attempt, char name[k_ra8_fmt_host_name_cap])
Form one collision-bounded private scratch leaf.
Anonymous raw-fd scratch artifacts for portable format verification.
size_t strlen(const char *s)
Calculate string length.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
char * strrchr(const char *s, int c)
Locate last occurrence of character in string.
static void internal_append(ra8_kbd_text_t *t, char ch)
Append character ch to the text buffer if capacity allows.
Caller-owned state for one unlinked scratch file.
int fd
Owned anonymous descriptor, or -1.
bool sealed
Positioned reads are now allowed.
uint64_t position
Bytes appended before sealing.
Caller-owned scratch artifact with append, seal, and read seams.