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

Fail-closed raw-fd host composition for portable format engines. More...

#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "ra8_attributes.h"
#include "ra8_fmt_host_fd_internal.h"
Include dependency graph for ra8_fmt_host_fd.c:

Go to the source code of this file.

Macros

#define _POSIX_C_SOURCE   (200809L)

Enumerations

enum  host_const_t : uint32_t {
  k_host_create_attempts = 16U ,
  k_host_decimal_radix = 10U ,
  k_host_mode_private = 0600U
}
 Host adapter bounds. More...

Functions

int renameat (int old_dir_fd, const char *old_path, int new_dir_fd, const char *new_path)
 Rename one directory-relative path to another atomically.
static ra8_err_t internal_pread (void *ctx, uint64_t offset, uint8_t *bytes, size_t len, size_t *got)
 Perform positioned reads with exact offset handling and legal short EOF.
static ra8_err_t internal_fd_write (void *ctx, const uint8_t *bytes, size_t len)
 Append all requested bytes to one descriptor.
static ra8_err_t internal_copy (char *out, size_t cap, const char *text, size_t len)
 Copy a bounded string slice and append NUL.
static ra8_err_t internal_split_path (const char *path, char parent[k_ra8_fmt_host_path_cap], char leaf[k_ra8_fmt_host_name_cap])
 Split a destination into a parent path and safe leaf name.
static ra8_err_t internal_name_u64 (char *name, size_t cap, size_t *len, uint64_t value)
 Append one unsigned decimal to a bounded stage name.
static ra8_err_t internal_stage_name (ra8_fmt_host_transaction_t *state, uint32_t attempt)
 Build a bounded sibling staging name.
static ra8_err_t internal_validate_destination (int parent_fd, const char *leaf)
 Reject existing non-regular or symlink destinations.
static ra8_err_t internal_transaction_append (void *ctx, const uint8_t *bytes, size_t len)
 Append transaction bytes exactly once.
static void internal_transaction_abort (void *ctx)
 Discard transaction-owned staging resources.
static ra8_err_t internal_transaction_commit (void *ctx)
 Sync, install, and directory-sync one staged artifact.
static void internal_snapshot (const struct stat *status, ra8_fmt_host_snapshot_t *out)
 Capture portable-width identity and mutation fields from host metadata.
static bool internal_snapshot_same (const ra8_fmt_host_snapshot_t *first, const ra8_fmt_host_snapshot_t *second)
 Compare complete captured regular-file evidence.
static ra8_err_t internal_source_validate (void *ctx, uint64_t expected_size)
 Portable source-validation callback over host snapshot evidence.
ra8_err_t priv_fmt_host_source_open (const char *path, uint64_t max_size, ra8_fmt_host_source_t *out)
 Open a bounded, regular, non-symlink input object.
bool priv_fmt_host_sources_same (const ra8_fmt_host_source_t *first, const ra8_fmt_host_source_t *second)
 Confirm two opens captured the same unchanged regular-file object.
ra8_err_t priv_fmt_host_source_unchanged (const ra8_fmt_host_source_t *source)
 Revalidate one open descriptor against its captured snapshot.
void priv_fmt_host_source_close (ra8_fmt_host_source_t *source)
 Close an open host source; safe after failed open.
ra8_fmt_sink_t priv_fmt_host_fd_sink (ra8_fmt_host_fd_sink_t *state)
 Obtain the exact-write portable sink for a raw descriptor.
void priv_fmt_host_log_byte (void *ctx, uint8_t byte)
 Adapt a logging byte to an injected raw-fd sink.
ra8_err_t priv_fmt_host_transaction_begin (const char *path, ra8_fmt_host_transaction_t *state, ra8_fmt_transaction_t *out)
 Begin a sibling-temp durable replacement transaction.

Variables

static const ra8_fmt_transaction_ops_t s_transaction_ops

Detailed Description

Fail-closed raw-fd host composition for portable format engines.

Adapts bounded positioned reads, exact writes, and same-directory durable transactions at the host edge without exposing hosted streams.

Since
0.1.0

Definition in file ra8_fmt_host_fd.c.

Macro Definition Documentation

◆ _POSIX_C_SOURCE

#define _POSIX_C_SOURCE   (200809L)

Definition at line 11 of file ra8_fmt_host_fd.c.

Enumeration Type Documentation

◆ host_const_t

enum host_const_t : uint32_t

Host adapter bounds.

Enumerator
k_host_create_attempts 

Collision-bounded stage creation.

k_host_decimal_radix 

Decimal name digit radix.

k_host_mode_private 

Staging-file permissions.

Definition at line 50 of file ra8_fmt_host_fd.c.

Function Documentation

◆ internal_copy()

ra8_err_t internal_copy ( char * out,
size_t cap,
const char * text,
size_t len )
static

Copy a bounded string slice and append NUL.

Rejects truncation before copying the exact payload and one terminator.

Parameters
[out]outDestination buffer.
[in]capDestination byte capacity.
[in]textSource slice.
[in]lenSource payload bytes excluding NUL.
Returns
Canonical bounded-copy status.
Return values
k_ra8_okComplete slice and terminator were stored.
k_ra8_err_invalid_sizeDestination capacity is insufficient.
Precondition
out spans cap bytes and text spans len bytes.
Source and destination ranges do not overlap.
Postcondition
Success sets out[len] to NUL without touching later bytes.
Failure leaves destination unchanged.
Note
Pure apart from caller output and thread-safe.
Since
0.1.0

Definition at line 160 of file ra8_fmt_host_fd.c.

References k_ra8_err_invalid_size, k_ra8_ok, and memcpy().

Referenced by internal_split_path().

◆ internal_fd_write()

ra8_err_t internal_fd_write ( void * ctx,
const uint8_t * bytes,
size_t len )
static

Append all requested bytes to one descriptor.

Retries interruptions and short writes until the whole span is accepted.

Parameters
[in,out]ctxBound ra8_fmt_host_fd_sink_t.
[in]bytesSource spanning len bytes when non-empty.
[in]lenExact requested byte count.
Returns
Canonical sink status.
Return values
k_ra8_okComplete span was written.
k_ra8_err_null_ptrRequired context or non-empty source was null.
k_ra8_failHost write failed or returned zero.
Precondition
ctx is non-null and bytes is valid for non-zero len.
Bound descriptor is open and writable.
Postcondition
Success advances descriptor position by exactly len.
Failure may leave a strict prefix in the caller-owned destination.
Note
Not thread-safe through one shared descriptor position.
Since
0.1.0

Definition at line 122 of file ra8_fmt_host_fd.c.

References ra8_fmt_host_fd_sink_t::fd, k_ra8_err_null_ptr, k_ra8_fail, and k_ra8_ok.

Referenced by internal_transaction_append(), priv_fmt_host_fd_sink(), and priv_fmt_host_log_byte().

◆ internal_name_u64()

ra8_err_t internal_name_u64 ( char * name,
size_t cap,
size_t * len,
uint64_t value )
static

Append one unsigned decimal to a bounded stage name.

Converts through a fixed reverse buffer and refuses name truncation.

Parameters
[in,out]nameExisting bounded name buffer.
[in]capTotal name capacity.
[in,out]lenCurrent length and resulting length.
[in]valueUnsigned value to append in base ten.
Returns
Canonical formatting status.
Return values
k_ra8_okDigits and NUL terminator were appended.
k_ra8_err_invalid_sizeComplete spelling does not fit.
Precondition
name spans cap bytes and is NUL-terminated at name[*len].
len is non-null and *len < cap.
Postcondition
Success advances len by the exact digit count.
Failure leaves len and name bytes unchanged.
Note
Pure apart from caller-owned name state.
Since
0.1.0

Definition at line 232 of file ra8_fmt_host_fd.c.

References k_host_decimal_radix, k_ra8_err_invalid_size, and k_ra8_ok.

Referenced by internal_stage_name().

◆ internal_pread()

ra8_err_t internal_pread ( void * ctx,
uint64_t offset,
uint8_t * bytes,
size_t len,
size_t * got )
static

Perform positioned reads with exact offset handling and legal short EOF.

Clamps requests to the captured regular-file size, retries interruptions, and reports bytes read without changing descriptor position.

Parameters
[in,out]ctxBound ra8_fmt_host_source_t.
[in]offsetAbsolute source offset.
[out]bytesDestination spanning len bytes when non-empty.
[in]lenRequested byte count.
[out]gotReceives actual bytes read.
Returns
Canonical source status.
Return values
k_ra8_okRead succeeded, including bounded EOF short reads.
k_ra8_err_null_ptrRequired context/output or non-empty buffer was null.
k_ra8_failHost positioned read failed.
Precondition
ctx and got are non-null and bytes is valid for non-zero len.
Source descriptor remains open and size is its captured regular-file extent.
Postcondition
got is initialized to the bytes transferred on every non-null path.
Descriptor stream position is unchanged.
Note
Thread-safe for independent destinations while the descriptor remains open.
Since
0.1.0

Definition at line 77 of file ra8_fmt_host_fd.c.

References ra8_fmt_host_source_t::fd, k_ra8_err_null_ptr, k_ra8_fail, k_ra8_ok, ra8_fmt_source_t::size, and ra8_fmt_host_source_t::source.

◆ internal_snapshot()

void internal_snapshot ( const struct stat * status,
ra8_fmt_host_snapshot_t * out )
static

Capture portable-width identity and mutation fields from host metadata.

Normalizes platform stat timestamps into the immutable source snapshot.

Parameters
[in]statusSuccessful regular-file metadata.
[out]outReceives every snapshot field.
Precondition
status and out are non-null.
status comes from fstat on the descriptor being bound.
Postcondition
out describes the same metadata observation.
No host descriptor or metadata object is modified.
Note
Pure apart from the caller output.
Since
0.1.0

Definition at line 436 of file ra8_fmt_host_fd.c.

Referenced by priv_fmt_host_source_open(), and priv_fmt_host_source_unchanged().

◆ internal_snapshot_same()

bool internal_snapshot_same ( const ra8_fmt_host_snapshot_t * first,
const ra8_fmt_host_snapshot_t * second )
static

Compare complete captured regular-file evidence.

Compares identity, size, and nanosecond modification/change times.

Parameters
[in]firstFirst snapshot.
[in]secondSecond snapshot.
Returns
Whether every captured field matches.
Return values
trueThe snapshots describe the same unchanged object.
falseIdentity, extent, or one timestamp differs.
Precondition
Both pointers are non-null.
Both snapshots were completely initialized.
Postcondition
Neither snapshot changes.
No external state is observed or modified.
Note
Pure and thread-safe.
Since
0.1.0

Definition at line 472 of file ra8_fmt_host_fd.c.

References ra8_fmt_host_snapshot_t::ctime_nsec, ra8_fmt_host_snapshot_t::ctime_sec, ra8_fmt_host_snapshot_t::device, ra8_fmt_host_snapshot_t::inode, ra8_fmt_host_snapshot_t::mtime_nsec, ra8_fmt_host_snapshot_t::mtime_sec, and ra8_fmt_host_snapshot_t::size.

Referenced by priv_fmt_host_source_unchanged(), and priv_fmt_host_sources_same().

◆ internal_source_validate()

ra8_err_t internal_source_validate ( void * ctx,
uint64_t expected_size )
static

Portable source-validation callback over host snapshot evidence.

Re-stats the open descriptor and compares it with its captured view.

Parameters
[in]ctxBound ra8_fmt_host_source_t.
[in]expected_sizeSize captured in the portable view.
Returns
Stability status.
Return values
k_ra8_okThe descriptor remains unchanged.
k_ra8_err_validation_failedSize or metadata changed.
otherHost metadata validation status.
Precondition
ctx points at an open source.
expected_size is the bound portable-view extent.
Postcondition
Descriptor position and snapshot remain unchanged.
Success proves all captured identity and mutation fields still match.
Note
Thread-safe against independent positioned reads.
Since
0.1.0

Definition at line 498 of file ra8_fmt_host_fd.c.

References k_ra8_err_validation_failed, priv_fmt_host_source_unchanged(), ra8_fmt_source_t::size, and ra8_fmt_host_source_t::source.

◆ internal_split_path()

ra8_err_t internal_split_path ( const char * path,
char parent[k_ra8_fmt_host_path_cap],
char leaf[k_ra8_fmt_host_name_cap] )
static

Split a destination into a parent path and safe leaf name.

Rejects empty, overlong, directory-only, and dot traversal leaves.

Parameters
[in]pathRequested destination path.
[out]parentReceives bounded parent path.
[out]leafReceives bounded final leaf.
Returns
Canonical path status.
Return values
k_ra8_okBoth components were initialized.
k_ra8_err_invalid_sizePath/component is empty or exceeds capacity.
k_ra8_err_invalid_argFinal leaf is . or ...
Precondition
Output arrays have their declared capacities.
path is null or NUL-terminated.
Postcondition
Success outputs reconstruct the requested path.
Failure touches no filesystem object.
Note
Pure and thread-safe.
Since
0.1.0

Definition at line 188 of file ra8_fmt_host_fd.c.

References internal_copy(), k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_fmt_host_name_cap, k_ra8_fmt_host_path_cap, k_ra8_ok, strlen(), and strrchr().

Referenced by priv_fmt_host_transaction_begin().

◆ internal_stage_name()

ra8_err_t internal_stage_name ( ra8_fmt_host_transaction_t * state,
uint32_t attempt )
static

Build a bounded sibling staging name.

Combines final leaf, fixed marker, process identifier, and attempt index.

Parameters
[in,out]stateTransaction state holding final and staging buffers.
[in]attemptExclusive-create collision retry index.
Returns
Canonical name-construction status.
Return values
k_ra8_okComplete hidden sibling leaf was built.
k_ra8_err_invalid_sizeFixed name capacity is insufficient.
Precondition
state is non-null and final_name is bounded and NUL-terminated.
attempt is below the fixed creation-attempt ceiling.
Postcondition
Success NUL-terminates state->stage_name with no slash.
No filesystem object is created.
Note
Not thread-safe through state.
Since
0.1.0

Definition at line 266 of file ra8_fmt_host_fd.c.

References ra8_fmt_host_transaction_t::final_name, internal_name_u64(), k_ra8_err_invalid_size, k_ra8_ok, memcpy(), ra8_fmt_host_transaction_t::stage_name, and strlen().

Referenced by priv_fmt_host_transaction_begin().

◆ internal_transaction_abort()

void internal_transaction_abort ( void * ctx)
static

Discard transaction-owned staging resources.

Idempotently closes descriptors and removes only the owned private leaf.

Parameters
[in,out]ctxPossibly partial ra8_fmt_host_transaction_t.
Precondition
ctx is null or points to caller-owned transaction state.
No append or commit uses the same transaction concurrently.
Postcondition
Every owned descriptor is closed and active state is false.
Any owned stage is unlinked; the final destination is unchanged.
Note
Best-effort cleanup intentionally has no return channel.
Since
0.1.0

Definition at line 360 of file ra8_fmt_host_fd.c.

References ra8_fmt_host_transaction_t::active, ra8_fmt_host_transaction_t::parent_fd, ra8_fmt_host_transaction_t::stage_exists, ra8_fmt_host_transaction_t::stage_fd, and ra8_fmt_host_transaction_t::stage_name.

Referenced by internal_transaction_commit(), and priv_fmt_host_transaction_begin().

◆ internal_transaction_append()

ra8_err_t internal_transaction_append ( void * ctx,
const uint8_t * bytes,
size_t len )
static

Append transaction bytes exactly once.

Writes the entire span through the raw descriptor sink and advances transaction position only after complete success.

Parameters
[in,out]ctxActive ra8_fmt_host_transaction_t.
[in]bytesSource span, nullable only when len is zero.
[in]lenExact append byte count.
Returns
Canonical transaction or sink status.
Return values
k_ra8_okComplete span was appended and accounted.
k_ra8_err_invalid_stateTransaction/source state was invalid.
otherRaw descriptor write failed.
Precondition
ctx points to an active transaction and stage descriptor is open.
bytes spans len readable bytes when non-empty.
Postcondition
Success advances position by exactly len.
Failure does not advance logical transaction position.
Note
Not thread-safe through one transaction.
Since
0.1.0

Definition at line 334 of file ra8_fmt_host_fd.c.

References ra8_fmt_host_transaction_t::active, internal_fd_write(), k_ra8_err_invalid_state, k_ra8_ok, ra8_fmt_host_transaction_t::position, and ra8_fmt_host_transaction_t::stage_fd.

◆ internal_transaction_commit()

ra8_err_t internal_transaction_commit ( void * ctx)
static

Sync, install, and directory-sync one staged artifact.

Syncs and closes staged bytes, performs one same-directory rename, then syncs the parent metadata and releases transaction ownership.

Parameters
[in,out]ctxActive ra8_fmt_host_transaction_t.
Returns
Canonical durable-publication status.
Return values
k_ra8_okFile sync, close, rename, and parent sync succeeded.
k_ra8_err_invalid_stateTransaction is not active with an open stage.
k_ra8_failA host durability or publication operation failed.
Precondition
ctx points to a complete active transaction.
No further append will use its stage descriptor.
Postcondition
Every owned descriptor is closed and active state is false.
Success leaves final path naming the complete staged bytes.
Note
Parent-sync failure may follow a visible successful rename.
Since
0.1.0

Definition at line 398 of file ra8_fmt_host_fd.c.

References ra8_fmt_host_transaction_t::active, ra8_fmt_host_transaction_t::final_name, internal_transaction_abort(), k_ra8_err_invalid_state, k_ra8_fail, k_ra8_ok, ra8_fmt_host_transaction_t::parent_fd, renameat(), ra8_fmt_host_transaction_t::stage_exists, ra8_fmt_host_transaction_t::stage_fd, and ra8_fmt_host_transaction_t::stage_name.

◆ internal_validate_destination()

ra8_err_t internal_validate_destination ( int parent_fd,
const char * leaf )
static

Reject existing non-regular or symlink destinations.

Performs a no-follow directory-relative stat and accepts absence or a regular file.

Parameters
[in]parent_fdOpen destination-parent descriptor.
[in]leafBounded final filename.
Returns
Canonical destination-policy status.
Return values
k_ra8_okDestination is absent or an existing regular file.
k_ra8_err_access_deniedDestination is symlink or non-regular.
k_ra8_failHost metadata lookup failed unexpectedly.
Precondition
parent_fd is an open directory descriptor.
leaf is non-null, NUL-terminated, and contains no slash.
Postcondition
No filesystem object is changed.
Success is only a point-in-time policy observation.
Note
Caller keeps the directory handle through publication.
Since
0.1.0

Definition at line 306 of file ra8_fmt_host_fd.c.

References AT_SYMLINK_NOFOLLOW, k_ra8_err_access_denied, k_ra8_fail, and k_ra8_ok.

Referenced by priv_fmt_host_transaction_begin().

◆ priv_fmt_host_fd_sink()

ra8_fmt_sink_t priv_fmt_host_fd_sink ( ra8_fmt_host_fd_sink_t * state)
nodiscard

Obtain the exact-write portable sink for a raw descriptor.

Definition at line 576 of file ra8_fmt_host_fd.c.

References internal_fd_write(), and RA8_PRIV.

Referenced by internal_open(), main(), priv_fmt_try_portable_convert(), priv_fmt_try_portable_inspect(), and priv_fmt_try_portable_verify().

◆ priv_fmt_host_log_byte()

void priv_fmt_host_log_byte ( void * ctx,
uint8_t byte )

Adapt a logging byte to an injected raw-fd sink.

Bridges the core logger's no-status byte callback to the same exact-write descriptor adapter used by portable reports.

Parameters
[in,out]ctxBound ra8_fmt_host_fd_sink_t.
[in]byteOne log byte.
Precondition
ctx points at a writable raw-fd sink for the callback lifetime.
The bound descriptor remains open during this call.
Postcondition
The byte was offered exactly once; host write failure is intentionally dropped.
No descriptor ownership or caller state changed.
Note
Matches the no-status byte-sink contract of ra8_log_set_byte_sink().
Since
0.1.0

Definition at line 581 of file ra8_fmt_host_fd.c.

References internal_fd_write(), and RA8_PRIV.

Referenced by main().

◆ priv_fmt_host_source_close()

void priv_fmt_host_source_close ( ra8_fmt_host_source_t * source)

Close an open host source; safe after failed open.

Releases only the raw descriptor and marks the host wrapper closed.

Parameters
[in,out]sourceHost source state, nullable for cleanup convenience.
Precondition
source is null or was initialized by the source-open operation.
No positioned read uses the same source concurrently.
Postcondition
Any owned descriptor is closed and set to -1.
A null or already-closed source is unchanged.
Note
Idempotent for sequential cleanup calls.
Since
0.1.0

Definition at line 568 of file ra8_fmt_host_fd.c.

References ra8_fmt_host_source_t::fd, and RA8_PRIV.

Referenced by internal_cleanup(), internal_open(), and priv_fmt_try_portable_convert().

◆ priv_fmt_host_source_open()

◆ priv_fmt_host_source_unchanged()

ra8_err_t priv_fmt_host_source_unchanged ( const ra8_fmt_host_source_t * source)
nodiscard

Revalidate one open descriptor against its captured snapshot.

Parameters
[in]sourceOpen source wrapper.
Returns
Canonical stability status.
Return values
k_ra8_okDescriptor still names the captured regular file.
k_ra8_err_validation_failedIdentity, size, or timestamps changed.
k_ra8_failHost metadata query failed.
Precondition
source came from a successful source-open call.
Postcondition
No descriptor position or captured field changes.
Note
Detects in-place concurrent mutation between verifier phase boundaries.
Since
0.1.0

Definition at line 550 of file ra8_fmt_host_fd.c.

References ra8_fmt_host_source_t::fd, internal_snapshot(), internal_snapshot_same(), k_ra8_err_invalid_state, k_ra8_err_validation_failed, k_ra8_fail, k_ra8_ok, RA8_PRIV, and ra8_fmt_host_source_t::snapshot.

Referenced by internal_open_and_size(), and internal_source_validate().

◆ priv_fmt_host_sources_same()

bool priv_fmt_host_sources_same ( const ra8_fmt_host_source_t * first,
const ra8_fmt_host_source_t * second )
nodiscard

Confirm two opens captured the same unchanged regular-file object.

Parameters
[in]firstFirst open source context.
[in]secondIndependent second open source context.
Returns
Whether identity, extent, and mutation timestamps match.
Precondition
Both sources came from successful host source-open calls.
Postcondition
Neither descriptor nor snapshot is changed.
Note
Pure over captured evidence.
Since
0.1.0

Definition at line 540 of file ra8_fmt_host_fd.c.

References ra8_fmt_host_source_t::fd, internal_snapshot_same(), RA8_PRIV, and ra8_fmt_host_source_t::snapshot.

Referenced by internal_open_and_size().

◆ priv_fmt_host_transaction_begin()

◆ renameat()

int renameat ( int old_dir_fd,
const char * old_path,
int new_dir_fd,
const char * new_path )
extern

Rename one directory-relative path to another atomically.

Declares the POSIX.1-2008 libc entry point at this raw-descriptor boundary without importing the hosted stream interface from the hosted stream header. The declaration matches the system-provided function; this translation unit does not provide an implementation.

Parameters
[in]old_dir_fdDirectory descriptor used to resolve old_path.
[in]old_pathNUL-terminated relative name of the staged artifact.
[in]new_dir_fdDirectory descriptor used to resolve new_path.
[in]new_pathNUL-terminated relative publication name.
Returns
POSIX operation status.
Return values
0The destination atomically replaced the source name.
-1The rename failed and errno identifies the cause.
Precondition
Both path pointers address valid NUL-terminated relative names.
Both descriptors refer to open directories accessible to the caller.
Postcondition
Success removes old_path and makes new_path name its prior object.
Failure preserves both directory entries and sets errno.
Note
This declaration exposes no hosted stream API and owns no descriptor.
Since
0.1.0

Referenced by internal_output_commit(), internal_output_commit(), internal_rename_opened(), internal_transaction_commit(), priv_mkfontimg_host_commit(), and priv_rv_trace_commit().

Variable Documentation

◆ s_transaction_ops

const ra8_fmt_transaction_ops_t s_transaction_ops
static
Initial value:
= {
}
static void internal_transaction_abort(void *ctx)
Discard transaction-owned staging resources.
static ra8_err_t internal_transaction_commit(void *ctx)
Sync, install, and directory-sync one staged artifact.
static ra8_err_t internal_transaction_append(void *ctx, const uint8_t *bytes, size_t len)
Append transaction bytes exactly once.

Definition at line 507 of file ra8_fmt_host_fd.c.

Referenced by priv_fmt_host_transaction_begin().