This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch releases/13.0 in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
commit c265c95c21bb2c42901b48f47e9dc65a8c68c448 Author: wangjianyu3 <[email protected]> AuthorDate: Thu Dec 25 15:22:48 2025 +0800 system/nxinit: Fix signal mask inheritance The init process has blocked all signals, spawned services would inherit that mask. This could cause services to miss important signals like SIGTERM during graceful shutdown. Signed-off-by: wangjianyu3 <[email protected]> --- system/nxinit/builtin.c | 72 ++++++++++++++++++++++++++++++++++++------------- system/nxinit/service.c | 29 +++++++++++++++++++- 2 files changed, 81 insertions(+), 20 deletions(-) diff --git a/system/nxinit/builtin.c b/system/nxinit/builtin.c index d300457f7..ba7a41bcf 100644 --- a/system/nxinit/builtin.c +++ b/system/nxinit/builtin.c @@ -183,6 +183,10 @@ static int cmd_exec(FAR struct action_manager_s *am, int init_builtin_run(FAR struct action_manager_s *am, int argc, FAR char **argv) { + char cmd[CONFIG_SYSTEM_NXINIT_RC_LINE_MAX]; + posix_spawnattr_t attr; + FAR char *args[4]; + sigset_t mask; pid_t pid; size_t i; int ret; @@ -203,35 +207,65 @@ int init_builtin_run(FAR struct action_manager_s *am, } } - ret = posix_spawnp(&pid, argv[0], NULL, NULL, argv, NULL); + ret = posix_spawnattr_init(&attr); if (ret != 0) { -#ifdef CONFIG_SYSTEM_SYSTEM - char cmd[CONFIG_SYSTEM_NXINIT_RC_LINE_MAX]; + init_err("posix_spawnattr_init %d", ret); + return -ret; + } - for (i = 0, cmd[i] = '\0'; i < argc; i++) + ret = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK); + if (ret != 0) + { + init_err("posix_spawnattr_setflags %d", ret); + posix_spawnattr_destroy(&attr); + return -ret; + } + + sigemptyset(&mask); + ret = posix_spawnattr_setsigmask(&attr, &mask); + if (ret != 0) + { + init_err("posix_spawnattr_setsigmask %d", ret); + posix_spawnattr_destroy(&attr); + return -ret; + } + + for (i = 0, cmd[i] = '\0'; i < argc; i++) + { + strlcat(cmd, argv[i], sizeof(cmd)); + if (i < argc - 1) { - strlcat(cmd, argv[i], sizeof(cmd)); - if (i < argc - 1) - { - strcat(cmd, " "); - } + strcat(cmd, " "); + } + } + + for (; ; ) + { + ret = posix_spawnp(&pid, argv[0], NULL, &attr, argv, NULL); + if (ret == 0) + { + init_debug("executed command '%s' pid %d", cmd, pid); + break; } - init_debug("Executing nsh command '%s'", cmd); - ret = system(cmd); - if (WIFEXITED(ret)) + if (!strcmp("sh", argv[0])) { - init_debug("NSH command '%s' exited %d", cmd, WEXITSTATUS(ret)); - return -WEXITSTATUS(ret); + init_err("executing command '%s': %d", cmd, ret); + init_dump_args(argc, argv); + pid = -ret; + break; } -#endif - init_err("Executing command '%s': %d", argv[0], ret); - init_dump_args(argc, argv); - return -ret; + init_debug("command '%s': %d", argv[0], ret); + args[0] = "sh"; + args[1] = "-c"; + args[2] = cmd; + args[3] = NULL; + argc = nitems(args) - 1; + argv = args; } - init_debug("Executed command '%s' pid %d", argv[0], pid); + posix_spawnattr_destroy(&attr); return pid; } diff --git a/system/nxinit/service.c b/system/nxinit/service.c index 7f582e6e4..7e840e7e7 100644 --- a/system/nxinit/service.c +++ b/system/nxinit/service.c @@ -427,6 +427,8 @@ void init_service_reap(FAR struct service_s *service, int status) int init_service_start(FAR struct service_s *service) { + posix_spawnattr_t attr; + sigset_t mask; int ret; int pid; @@ -439,8 +441,33 @@ int init_service_start(FAR struct service_s *service) return service->pid; } - ret = posix_spawnp(&pid, service->argv[2], NULL, NULL, &service->argv[2], + ret = posix_spawnattr_init(&attr); + if (ret != 0) + { + init_err("posix_spawnattr_init %d", ret); + return -ret; + } + + ret = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK); + if (ret != 0) + { + init_err("posix_spawnattr_setflags %d", ret); + posix_spawnattr_destroy(&attr); + return -ret; + } + + sigemptyset(&mask); + ret = posix_spawnattr_setsigmask(&attr, &mask); + if (ret != 0) + { + init_err("posix_spawnattr_setsigmask %d", ret); + posix_spawnattr_destroy(&attr); + return -ret; + } + + ret = posix_spawnp(&pid, service->argv[2], NULL, &attr, &service->argv[2], environ); + posix_spawnattr_destroy(&attr); if (ret != 0) { init_err("Starting service '%s': %d", service->argv[1], ret);
