init: Handle SIGCHLD signals
This commit is contained in:
parent
5f0830cd41
commit
81131ad3a8
102
apps/init.cpp
102
apps/init.cpp
@ -365,6 +365,40 @@ static void mount_devpts()
|
|||||||
if (mount("/dev/pts", "devpts", "devpts") < 0) exit(255);
|
if (mount("/dev/pts", "devpts", "devpts") < 0) exit(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wait_for_child(int)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
auto rc = os::Process::wait(os::Process::ANY_CHILD, &status);
|
||||||
|
if (rc.has_error())
|
||||||
|
{
|
||||||
|
do_log("[init] waitpid error %s", rc.error_string());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t child = rc.release_value();
|
||||||
|
|
||||||
|
for (auto& service : g_services)
|
||||||
|
{
|
||||||
|
if (service.pid.has_value() && service.pid.value() == child)
|
||||||
|
{
|
||||||
|
if (WIFEXITED(status))
|
||||||
|
{
|
||||||
|
do_log("[init] service %s exited with status %d\n", service.name.chars(), WEXITSTATUS(status));
|
||||||
|
}
|
||||||
|
else { do_log("[init] service %s was terminated by signal %d\n", service.name.chars(), WTERMSIG(status)); }
|
||||||
|
|
||||||
|
if (service.restart)
|
||||||
|
{
|
||||||
|
do_log("[init] restarting service %s\n", service.name.chars());
|
||||||
|
|
||||||
|
start_service(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Result<int> sysinit(StringView path)
|
Result<int> sysinit(StringView path)
|
||||||
{
|
{
|
||||||
if (getpid() != 1)
|
if (getpid() != 1)
|
||||||
@ -404,38 +438,7 @@ Result<int> sysinit(StringView path)
|
|||||||
if (path.is_empty()) path = "/etc/init";
|
if (path.is_empty()) path = "/etc/init";
|
||||||
start_services(path);
|
start_services(path);
|
||||||
|
|
||||||
while (1)
|
while (1) { wait_for_child(0); }
|
||||||
{
|
|
||||||
int status;
|
|
||||||
auto rc = os::Process::wait(os::Process::ANY_CHILD, &status);
|
|
||||||
if (rc.has_error()) continue;
|
|
||||||
|
|
||||||
pid_t child = rc.release_value();
|
|
||||||
|
|
||||||
for (auto& service : g_services)
|
|
||||||
{
|
|
||||||
if (service.pid.has_value() && service.pid.value() == child)
|
|
||||||
{
|
|
||||||
if (WIFEXITED(status))
|
|
||||||
{
|
|
||||||
do_log("[init] service %s exited with status %d\n", service.name.chars(), WEXITSTATUS(status));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
do_log("[init] service %s was terminated by signal %d\n", service.name.chars(), WTERMSIG(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (service.restart)
|
|
||||||
{
|
|
||||||
do_log("[init] restarting service %s\n", service.name.chars());
|
|
||||||
|
|
||||||
start_service(service);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<int> user_init(StringView path)
|
Result<int> user_init(StringView path)
|
||||||
@ -454,38 +457,7 @@ Result<int> user_init(StringView path)
|
|||||||
|
|
||||||
TRY(os::Security::pledge("stdio rpath wpath proc exec", nullptr));
|
TRY(os::Security::pledge("stdio rpath wpath proc exec", nullptr));
|
||||||
|
|
||||||
while (1)
|
while (1) { wait_for_child(0); }
|
||||||
{
|
|
||||||
int status;
|
|
||||||
auto rc = os::Process::wait(os::Process::ANY_CHILD, &status);
|
|
||||||
if (rc.has_error()) continue;
|
|
||||||
|
|
||||||
pid_t child = rc.release_value();
|
|
||||||
|
|
||||||
for (auto& service : g_services)
|
|
||||||
{
|
|
||||||
if (service.pid.has_value() && service.pid.value() == child)
|
|
||||||
{
|
|
||||||
if (WIFEXITED(status))
|
|
||||||
{
|
|
||||||
do_log("[init] service %s exited with status %d\n", service.name.chars(), WEXITSTATUS(status));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
do_log("[init] service %s was terminated by signal %d\n", service.name.chars(), WTERMSIG(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (service.restart)
|
|
||||||
{
|
|
||||||
do_log("[init] restarting service %s\n", service.name.chars());
|
|
||||||
|
|
||||||
start_service(service);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<int> luna_main(int argc, char** argv)
|
Result<int> luna_main(int argc, char** argv)
|
||||||
@ -501,6 +473,8 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
"change the default service path (/etc/init or /etc/user)");
|
"change the default service path (/etc/init or /etc/user)");
|
||||||
parser.parse(argc, argv);
|
parser.parse(argc, argv);
|
||||||
|
|
||||||
|
signal(SIGCHLD, wait_for_child);
|
||||||
|
|
||||||
if (user) return user_init(service_path);
|
if (user) return user_init(service_path);
|
||||||
return sysinit(service_path);
|
return sysinit(service_path);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user