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);

Reply via email to