summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-09-04 22:36:06 +0200
committerAndreas Kling <kling@serenityos.org>2021-09-04 23:11:04 +0200
commit3b995c6d01239cf2099b764917082284fea30c31 (patch)
tree9424990293525c0e5dda6d6178cdf6315729fe2d
parentba1a6ca971fcdd8ff145af995d2cbb963ec3f3c3 (diff)
downloadserenity-3b995c6d01239cf2099b764917082284fea30c31.zip
Kernel: Tidy up Process::try_create_user_process()
This function is currently only ever used to create the init process (SystemServer). It had a few idiosyncratic things about it that this patch cleans up: - Errors were returned in an int& out-param. - It had a path for non-0 process PIDs which was never taken.
-rw-r--r--Kernel/Process.cpp34
-rw-r--r--Kernel/Process.h2
-rw-r--r--Kernel/init.cpp11
3 files changed, 19 insertions, 28 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index 37d400b9d9..87575a2f6e 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -143,32 +143,26 @@ void Process::register_new(Process& process)
});
}
-RefPtr<Process> Process::create_user_process(RefPtr<Thread>& first_thread, const String& path, UserID uid, GroupID gid, ProcessID parent_pid, int& error, Vector<String>&& arguments, Vector<String>&& environment, TTY* tty)
+KResultOr<NonnullRefPtr<Process>> Process::try_create_user_process(RefPtr<Thread>& first_thread, String const& path, UserID uid, GroupID gid, Vector<String> arguments, Vector<String> environment, TTY* tty)
{
auto parts = path.split('/');
if (arguments.is_empty()) {
arguments.append(parts.last());
}
- RefPtr<Custody> cwd;
- if (auto parent = Process::from_pid(parent_pid))
- cwd = parent->m_cwd;
- if (!cwd)
- cwd = VirtualFileSystem::the().root_custody();
-
- auto process = Process::try_create(first_thread, parts.take_last(), uid, gid, parent_pid, false, move(cwd), nullptr, tty);
+ auto process = Process::try_create(first_thread, parts.take_last(), uid, gid, ProcessID(0), false, VirtualFileSystem::the().root_custody(), nullptr, tty);
if (!process || !first_thread)
- return {};
+ return ENOMEM;
+
if (!process->m_fds.try_resize(process->m_fds.max_open())) {
first_thread = nullptr;
- return {};
+ return ENOMEM;
}
auto& device_to_use_as_tty = tty ? (CharacterDevice&)*tty : NullDevice::the();
auto description_or_error = device_to_use_as_tty.open(O_RDWR);
- if (description_or_error.is_error()) {
- error = description_or_error.error().error();
- return {};
- }
+ if (description_or_error.is_error())
+ return description_or_error.error();
+
auto& description = description_or_error.value();
auto setup_description = [&process, &description](int fd) {
@@ -179,20 +173,18 @@ RefPtr<Process> Process::create_user_process(RefPtr<Thread>& first_thread, const
setup_description(1);
setup_description(2);
- error = process->exec(path, move(arguments), move(environment)).error();
- if (error != 0) {
- dbgln("Failed to exec {}: {}", path, error);
+ if (auto result = process->exec(path, move(arguments), move(environment)); result.is_error()) {
+ dbgln("Failed to exec {}: {}", path, result);
first_thread = nullptr;
- return {};
+ return result;
}
register_new(*process);
- error = 0;
// NOTE: All user processes have a leaked ref on them. It's balanced by Thread::WaitBlockerSet::finalize().
- (void)process.leak_ref();
+ process->ref();
- return process;
+ return process.release_nonnull();
}
RefPtr<Process> Process::create_kernel_process(RefPtr<Thread>& first_thread, String&& name, void (*entry)(void*), void* entry_data, u32 affinity, RegisterProcess do_register)
diff --git a/Kernel/Process.h b/Kernel/Process.h
index 46dadded75..86cbc1d87e 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -179,7 +179,7 @@ public:
}
static RefPtr<Process> create_kernel_process(RefPtr<Thread>& first_thread, String&& name, void (*entry)(void*), void* entry_data = nullptr, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes);
- static RefPtr<Process> create_user_process(RefPtr<Thread>& first_thread, const String& path, UserID, GroupID, ProcessID ppid, int& error, Vector<String>&& arguments = Vector<String>(), Vector<String>&& environment = Vector<String>(), TTY* = nullptr);
+ static KResultOr<NonnullRefPtr<Process>> try_create_user_process(RefPtr<Thread>& first_thread, String const& path, UserID, GroupID, Vector<String> arguments, Vector<String> environment, TTY*);
static void register_new(Process&);
bool unref() const;
diff --git a/Kernel/init.cpp b/Kernel/init.cpp
index 1da79c63c9..ebb84c030b 100644
--- a/Kernel/init.cpp
+++ b/Kernel/init.cpp
@@ -336,18 +336,17 @@ void init_stage2(void*)
// NOTE: Everything in the .ksyms section becomes inaccessible after this point.
MM.unmap_ksyms_after_init();
- int error;
-
// FIXME: It would be nicer to set the mode from userspace.
// FIXME: It would be smarter to not hardcode that the first tty is the only graphical one
ConsoleManagement::the().first_tty()->set_graphical(GraphicsManagement::the().framebuffer_devices_exist());
RefPtr<Thread> thread;
auto userspace_init = kernel_command_line().userspace_init();
auto init_args = kernel_command_line().userspace_init_args();
- Process::create_user_process(thread, userspace_init, UserID(0), GroupID(0), ProcessID(0), error, move(init_args), {}, tty0);
- if (error != 0) {
- PANIC("init_stage2: Error spawning SystemServer: {}", error);
- }
+
+ auto init_or_error = Process::try_create_user_process(thread, userspace_init, UserID(0), GroupID(0), move(init_args), {}, tty0);
+ if (init_or_error.is_error())
+ PANIC("init_stage2: Error spawning init process: {}", init_or_error.error());
+
thread->set_priority(THREAD_PRIORITY_HIGH);
if (boot_profiling) {