init: Use pledge and support init --user
This commit is contained in:
parent
9954fc1658
commit
cfb60fad25
@ -4,9 +4,11 @@
|
|||||||
#include <luna/Sort.h>
|
#include <luna/Sort.h>
|
||||||
#include <luna/String.h>
|
#include <luna/String.h>
|
||||||
#include <luna/Vector.h>
|
#include <luna/Vector.h>
|
||||||
|
#include <os/ArgumentParser.h>
|
||||||
#include <os/Directory.h>
|
#include <os/Directory.h>
|
||||||
#include <os/File.h>
|
#include <os/File.h>
|
||||||
#include <os/Process.h>
|
#include <os/Process.h>
|
||||||
|
#include <os/Security.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -247,9 +249,9 @@ static Result<void> load_service(const os::Path& path)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result<void> load_services()
|
static Result<void> load_services(StringView path)
|
||||||
{
|
{
|
||||||
auto dir = TRY(os::Directory::open("/etc/init"));
|
auto dir = TRY(os::Directory::open(path));
|
||||||
|
|
||||||
auto services = TRY(dir->list_names(os::Directory::Filter::ParentAndBase));
|
auto services = TRY(dir->list_names(os::Directory::Filter::ParentAndBase));
|
||||||
sort(services.begin(), services.end(), String::compare);
|
sort(services.begin(), services.end(), String::compare);
|
||||||
@ -259,9 +261,9 @@ static Result<void> load_services()
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result<void> start_services()
|
static Result<void> start_services(StringView path)
|
||||||
{
|
{
|
||||||
TRY(load_services());
|
TRY(load_services(path));
|
||||||
for (auto& service : g_services)
|
for (auto& service : g_services)
|
||||||
{
|
{
|
||||||
do_log("[init] starting service %s\n", service.name.chars());
|
do_log("[init] starting service %s\n", service.name.chars());
|
||||||
@ -301,7 +303,7 @@ static void mount_shmfs()
|
|||||||
if (chmod("/dev/shm", 01777) < 0) exit(255);
|
if (chmod("/dev/shm", 01777) < 0) exit(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
Result<int> sysinit()
|
||||||
{
|
{
|
||||||
if (getpid() != 1)
|
if (getpid() != 1)
|
||||||
{
|
{
|
||||||
@ -315,6 +317,8 @@ int main()
|
|||||||
stdout = fopen("/dev/console", "w");
|
stdout = fopen("/dev/console", "w");
|
||||||
stderr = fopen("/dev/console", "w");
|
stderr = fopen("/dev/console", "w");
|
||||||
|
|
||||||
|
TRY(os::Security::pledge("stdio rpath wpath cpath fattr host mount proc exec signal", nullptr));
|
||||||
|
|
||||||
mount_tmpfs();
|
mount_tmpfs();
|
||||||
mount_shmfs();
|
mount_shmfs();
|
||||||
|
|
||||||
@ -330,7 +334,11 @@ int main()
|
|||||||
if (signal(SIGTERM, sigterm_handler) == SIG_ERR) do_log("[init] failed to register handler for SIGTERM\n");
|
if (signal(SIGTERM, sigterm_handler) == SIG_ERR) do_log("[init] failed to register handler for SIGTERM\n");
|
||||||
if (signal(SIGQUIT, sigquit_handler) == SIG_ERR) do_log("[init] failed to register handler for SIGQUIT\n");
|
if (signal(SIGQUIT, sigquit_handler) == SIG_ERR) do_log("[init] failed to register handler for SIGQUIT\n");
|
||||||
|
|
||||||
start_services();
|
TRY(os::Security::pledge("stdio rpath wpath cpath proc exec", nullptr));
|
||||||
|
|
||||||
|
start_services("/etc/init");
|
||||||
|
|
||||||
|
TRY(os::Security::pledge("stdio rpath wpath proc exec", nullptr));
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -365,3 +373,66 @@ int main()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<int> user_init()
|
||||||
|
{
|
||||||
|
setpgid(0, 0);
|
||||||
|
|
||||||
|
g_init_log = fopen("/dev/uart0", "w");
|
||||||
|
check(g_init_log);
|
||||||
|
setlinebuf(g_init_log);
|
||||||
|
fcntl(fileno(g_init_log), F_SETFD, FD_CLOEXEC);
|
||||||
|
|
||||||
|
TRY(os::Security::pledge("stdio rpath wpath cpath proc exec", nullptr));
|
||||||
|
|
||||||
|
start_services("/etc/user");
|
||||||
|
|
||||||
|
TRY(os::Security::pledge("stdio rpath wpath proc exec", nullptr));
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
bool user;
|
||||||
|
|
||||||
|
os::ArgumentParser parser;
|
||||||
|
parser.add_description("The init system for Luna.");
|
||||||
|
parser.add_system_program_info("init"_sv);
|
||||||
|
parser.add_switch_argument(user, 'u', "user"_sv, "initialize a user session instead of the system");
|
||||||
|
parser.parse(argc, argv);
|
||||||
|
|
||||||
|
if (user) return user_init();
|
||||||
|
return sysinit();
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user