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/String.h>
|
||||
#include <luna/Vector.h>
|
||||
#include <os/ArgumentParser.h>
|
||||
#include <os/Directory.h>
|
||||
#include <os/File.h>
|
||||
#include <os/Process.h>
|
||||
#include <os/Security.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -247,9 +249,9 @@ static Result<void> load_service(const os::Path& path)
|
||||
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));
|
||||
sort(services.begin(), services.end(), String::compare);
|
||||
@ -259,9 +261,9 @@ static Result<void> load_services()
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
int main()
|
||||
Result<int> sysinit()
|
||||
{
|
||||
if (getpid() != 1)
|
||||
{
|
||||
@ -315,6 +317,8 @@ int main()
|
||||
stdout = 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_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(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)
|
||||
{
|
||||
@ -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