mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-08-01 20:29:00 +00:00
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 <wangjianyu3@xiaomi.com>
This commit is contained in:
parent
09a3e90d60
commit
51c542b75e
2 changed files with 87 additions and 26 deletions
|
|
@ -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];
|
||||
|
||||
for (i = 0, cmd[i] = '\0'; i < argc; i++)
|
||||
{
|
||||
strlcat(cmd, argv[i], sizeof(cmd));
|
||||
if (i < argc - 1)
|
||||
{
|
||||
strcat(cmd, " ");
|
||||
}
|
||||
}
|
||||
|
||||
init_debug("Executing nsh command '%s'", cmd);
|
||||
ret = system(cmd);
|
||||
if (WIFEXITED(ret))
|
||||
{
|
||||
init_debug("NSH command '%s' exited %d", cmd, WEXITSTATUS(ret));
|
||||
return -WEXITSTATUS(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
init_err("Executing command '%s': %d", argv[0], ret);
|
||||
init_dump_args(argc, argv);
|
||||
init_err("posix_spawnattr_init %d", ret);
|
||||
return -ret;
|
||||
}
|
||||
|
||||
init_debug("Executed command '%s' pid %d", argv[0], pid);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (!strcmp("sh", argv[0]))
|
||||
{
|
||||
init_err("executing command '%s': %d", cmd, ret);
|
||||
init_dump_args(argc, argv);
|
||||
pid = -ret;
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
posix_spawnattr_destroy(&attr);
|
||||
return pid;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue