This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
commit d79d8107b3e08494e73f87df6ec6163fd6a9b5a2 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);
