SafeAPI Backend POSIX
POSIX/Linux OAL backend for safeAPIFreamwork
Loading...
Searching...
No Matches
sapi_posix_backend_reboot.c File Reference

POSIX sapi_reboot backend: execv() re-exec of the current binary (ADR-018 section 2.3), resolved portably per-OS since there is no single POSIX-standard way to ask "what is my own executable path.". More...

#include "safeapi/posix_backend/sapi_posix_backend.h"
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
Include dependency graph for sapi_posix_backend_reboot.c:

Go to the source code of this file.

Macros

#define _XOPEN_SOURCE   700
#define SAPI_POSIX_REBOOT_MAX_ARGV   8U

Functions

static bool resolve_self_exe_path (char *out_path, size_t out_path_size, const char *argv0)
static sapi_status_t backend_request (uint16_t reason_code)
void sapi_posix_backend_reboot_set_argv (int argc, char *const argv[])
 Registers the original process argv[] the POSIX reboot backend should re-exec with (instead of its own placeholder argv[0]). Call once, early in main(), with the same argc/argv main() itself received - e.g. right after this project's own argv parsing (role/site), so a REBOOT-triggered re-exec restarts the SAME role for the SAME site rather than losing that information and falling back to a placeholder command line the freshly re-exec'd process cannot make sense of.
const sapi_reboot_backend_t * sapi_posix_backend_reboot (void)
 The POSIX sapi_reboot backend (execv() re-exec of the current process image, self-path resolved portably per-OS - see sapi_posix_backend_reboot.c's file header).

Variables

char ** environ
static char * s_registered_argv [SAPI_POSIX_REBOOT_MAX_ARGV+1U]
static bool s_argv_registered = false
static const sapi_reboot_backend_t s_posix_reboot_backend = { backend_request }

Detailed Description

POSIX sapi_reboot backend: execv() re-exec of the current binary (ADR-018 section 2.3), resolved portably per-OS since there is no single POSIX-standard way to ask "what is my own executable path.".

This is explicitly a stand-in, not a real safety-relevant reboot path. A normal (non-root, non-embedded) process cannot reset the CPU; re-exec is the closest available approximation - it restarts the process image from main() with the original argv, which exercises the same "system comes back up from a clean start" application-level contract a real reset would, without actually resetting anything below the process. A real deployment on real hardware needs a real reset mechanism (watchdog-triggered hardware reset, supervisory process that respawns this one, etc.) - see ADR-018 section 3.

Path resolution is the only genuinely OS-specific part:

  • Linux: /proc/self/exe (a symlink the kernel maintains - no size limit worry, execv() can follow it directly).
  • macOS: no /proc filesystem exists at all; _NSGetExecutablePath() (mach-o/dyld.h) is the documented Apple API for "the path used to execute the current process," queried in the standard two-call pattern (first call reports the required buffer size). This project's actual dev/verification host is macOS, so this path is not a hypothetical - REBOOT would silently degrade to SAPI_STATUS_NOT_SUPPORTED (and this backend's caller would fall through to sapi_safestate's defensive halt) without it. Any other UNIX falls back to argv[0] as a last resort (may fail if argv[0] was not a full/resolvable path, e.g. found only via $PATH - documented limitation, not silently pretended away).

reason_code is passed via an environment variable (SAPI_REBOOT_REASON_CODE) rather than argv, so it survives the re-exec without disturbing the caller's original argv[] the new process image receives; a real backend on real hardware would instead persist it to NVM/black-box storage before resetting (REQ-OAL-REBOOT-010's doc comment), which is out of this stand-in's scope.

argv[] the re-exec'd image actually receives: sapi_posix_backend_ reboot_set_argv() (sapi_posix_backend.h), if the caller registered it, takes priority - execv()'ing with the SAME argv main() itself originally received is what lets a caller whose behavior depends on its own command-line arguments (e.g. safeAPIRBC2oo2's own role/site - see its main.c) resume as the same role after the reboot, not lose that information to a placeholder command line. Without it, this falls back to a self-contained placeholder argv (see backend_request() below) - fine for a caller with no argv-dependent behavior of its own.

Definition in file sapi_posix_backend_reboot.c.

Macro Definition Documentation

◆ _XOPEN_SOURCE

#define _XOPEN_SOURCE   700

Definition at line 4 of file sapi_posix_backend_reboot.c.

◆ SAPI_POSIX_REBOOT_MAX_ARGV

#define SAPI_POSIX_REBOOT_MAX_ARGV   8U

Local makros

Definition at line 76 of file sapi_posix_backend_reboot.c.

Function Documentation

◆ backend_request()

sapi_status_t backend_request ( uint16_t reason_code)
static

Definition at line 159 of file sapi_posix_backend_reboot.c.

◆ resolve_self_exe_path()

bool resolve_self_exe_path ( char * out_path,
size_t out_path_size,
const char * argv0 )
static

Local types declarations Local function declarations Resolves this process's own executable path into out_path (capacity out_path_size bytes, NUL-terminated on success).

Returns
true on success; false if the path could not be resolved (out_path is left unmodified) - the caller falls back to argv0 in that case.

Definition at line 122 of file sapi_posix_backend_reboot.c.

◆ sapi_posix_backend_reboot()

const sapi_reboot_backend_t * sapi_posix_backend_reboot ( void )

The POSIX sapi_reboot backend (execv() re-exec of the current process image, self-path resolved portably per-OS - see sapi_posix_backend_reboot.c's file header).

Definition at line 114 of file sapi_posix_backend_reboot.c.

◆ sapi_posix_backend_reboot_set_argv()

void sapi_posix_backend_reboot_set_argv ( int argc,
char *const argv[] )

Registers the original process argv[] the POSIX reboot backend should re-exec with (instead of its own placeholder argv[0]). Call once, early in main(), with the same argc/argv main() itself received - e.g. right after this project's own argv parsing (role/site), so a REBOOT-triggered re-exec restarts the SAME role for the SAME site rather than losing that information and falling back to a placeholder command line the freshly re-exec'd process cannot make sense of.

Global variables declarations Global functions

Not calling this at all is still valid - the backend then falls back to its original placeholder-argv behavior (see sapi_posix_backend_reboot.c), which is fine for a caller whose own main() takes no arguments it needs preserved across a reboot.

Parameters
argcArgument count, as received by main(). Only the first SAPI_POSIX_REBOOT_MAX_ARGV entries are retained (the backend has no dynamic allocation - REQ-OAL-REBOOT-001's fixed-storage convention).
argvArgument vector, as received by main(). The pointers themselves are stored (not copied) - valid because argv's string storage is guaranteed to remain valid for the whole process lifetime, same as main()'s own copy of it. Must not be NULL if argc > 0.

Definition at line 97 of file sapi_posix_backend_reboot.c.

Variable Documentation

◆ s_argv_registered

bool s_argv_registered = false
static

Definition at line 90 of file sapi_posix_backend_reboot.c.

◆ s_posix_reboot_backend

const sapi_reboot_backend_t s_posix_reboot_backend = { backend_request }
static

Definition at line 91 of file sapi_posix_backend_reboot.c.

◆ s_registered_argv

char* s_registered_argv[SAPI_POSIX_REBOOT_MAX_ARGV+1U]
static

Local variables declarations

Definition at line 89 of file sapi_posix_backend_reboot.c.