zephyr/boards/native/native_sim/reboot_bottom.c
Adrian Friedli ffdc50c4bf boards: native_sim: add reboot for native_sim
Add a reboot implementation for the native_sim target which restarts
the current executable keeping the command line arguments after closing
all open file descriptors.

Signed-off-by: Adrian Friedli <adrian.friedli@husqvarnagroup.com>
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
Co-authored-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
2025-04-29 17:54:26 +02:00

75 lines
1.4 KiB
C

/*
* Copyright (c) 2025 GARDENA GmbH
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <nsi_main.h>
#include <nsi_tasks.h>
#include <nsi_tracing.h>
#include <nsi_cmdline.h>
static const char module[] = "native_sim_reboot";
static long close_open_fds(void)
{
/* close all open file descriptors except 0-2 */
errno = 0;
long max_fd = sysconf(_SC_OPEN_MAX);
if (max_fd < 0) {
if (errno != 0) {
nsi_print_error_and_exit("%s: %s\n", module, strerror(errno));
} else {
nsi_print_warning("%s: Cannot determine maximum number of file descriptors"
"\n",
module);
}
return max_fd;
}
for (int fd = 3; fd < max_fd; fd++) {
(void)close(fd);
}
return 0;
}
static bool reboot_on_exit;
void native_set_reboot_on_exit(void)
{
reboot_on_exit = true;
}
void maybe_reboot(void)
{
char **argv;
int argc;
if (!reboot_on_exit) {
return;
}
reboot_on_exit = false; /* If we reenter it means we failed to reboot */
nsi_get_cmd_line_args(&argc, &argv);
if (close_open_fds() < 0) {
nsi_exit(1);
}
nsi_print_warning("%s: Restarting process.\n", module);
(void)execv("/proc/self/exe", argv);
nsi_print_error_and_exit("%s: Failed to restart process, exiting (%s)\n", module,
strerror(errno));
}
NSI_TASK(maybe_reboot, ON_EXIT_POST, 999);