|
@@ -275,17 +275,23 @@ Process::Process(const String& name, UserID uid, GroupID gid, ProcessID ppid, bo
|
|
|
KResult Process::attach_resources(NonnullOwnPtr<Memory::AddressSpace>&& preallocated_space, RefPtr<Thread>& first_thread, Process* fork_parent)
|
|
|
{
|
|
|
m_space = move(preallocated_space);
|
|
|
- if (fork_parent) {
|
|
|
- // NOTE: fork() doesn't clone all threads; the thread that called fork() becomes the only thread in the new process.
|
|
|
- first_thread = Thread::current()->clone(*this);
|
|
|
- if (!first_thread)
|
|
|
- return ENOMEM;
|
|
|
- } else {
|
|
|
+
|
|
|
+ auto thread_or_error = [&] {
|
|
|
+ if (fork_parent) {
|
|
|
+ // NOTE: fork() doesn't clone all threads; the thread that called fork() becomes the only thread in the new process.
|
|
|
+ return Thread::current()->try_clone(*this);
|
|
|
+ }
|
|
|
// NOTE: This non-forked code path is only taken when the kernel creates a process "manually" (at boot.)
|
|
|
- auto thread_or_error = Thread::try_create(*this);
|
|
|
- if (thread_or_error.is_error())
|
|
|
- return thread_or_error.error();
|
|
|
- first_thread = thread_or_error.release_value();
|
|
|
+ return Thread::try_create(*this);
|
|
|
+ }();
|
|
|
+
|
|
|
+ if (thread_or_error.is_error())
|
|
|
+ return thread_or_error.error();
|
|
|
+
|
|
|
+ first_thread = thread_or_error.release_value();
|
|
|
+
|
|
|
+ if (!fork_parent) {
|
|
|
+ // FIXME: Figure out if this is really necessary.
|
|
|
first_thread->detach();
|
|
|
}
|
|
|
return KSuccess;
|