diff options
author | Andreas Kling <kling@serenityos.org> | 2021-09-04 22:36:06 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-09-04 23:11:04 +0200 |
commit | 3b995c6d01239cf2099b764917082284fea30c31 (patch) | |
tree | 9424990293525c0e5dda6d6178cdf6315729fe2d | |
parent | ba1a6ca971fcdd8ff145af995d2cbb963ec3f3c3 (diff) | |
download | serenity-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.cpp | 34 | ||||
-rw-r--r-- | Kernel/Process.h | 2 | ||||
-rw-r--r-- | Kernel/init.cpp | 11 |
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) { |