Kernel: Allow fork to fail at any point

This commit is contained in:
2026-07-02 19:39:59 +03:00
parent 6d1696b77e
commit 991f7024d5

View File

@@ -863,13 +863,30 @@ namespace Kernel
); );
Process* forked = create_process(m_credentials, m_pid, m_sid, m_pgrp); Process* forked = create_process(m_credentials, m_pid, m_sid, m_pgrp);
BAN::ScopeGuard process_deleter([forked] {
forked->m_page_table.clear();
delete forked;
});
forked->m_page_table = BAN::move(page_table);
Thread* thread = TRY(Thread::current().clone(forked, sp, ip));
BAN::ScopeGuard thread_deleter([thread] { delete thread; });
// NOTE: make sure the last two `MUST`s don't fail
TRY(forked->m_threads.reserve(1));
TRY(Processor::scheduler().bind_thread_to_processor(thread, Processor::current_id()));
{
SpinLockGuard _(s_process_lock);
TRY(s_processes.push_back(forked));
}
forked->m_controlling_terminal = m_controlling_terminal; forked->m_controlling_terminal = m_controlling_terminal;
forked->m_working_directory = BAN::move(working_directory); forked->m_working_directory = BAN::move(working_directory);
forked->m_root_file = BAN::move(root_file); forked->m_root_file = BAN::move(root_file);
forked->m_cmdline = BAN::move(cmdline); forked->m_cmdline = BAN::move(cmdline);
forked->m_environ = BAN::move(environ); forked->m_environ = BAN::move(environ);
forked->m_executable = BAN::move(executable); forked->m_executable = BAN::move(executable);
forked->m_page_table = BAN::move(page_table);
forked->m_shared_page_vaddr = BAN::move(shared_page_vaddr); forked->m_shared_page_vaddr = BAN::move(shared_page_vaddr);
forked->m_open_file_descriptors = BAN::move(*open_file_descriptors); forked->m_open_file_descriptors = BAN::move(*open_file_descriptors);
forked->m_mapped_regions = BAN::move(mapped_regions); forked->m_mapped_regions = BAN::move(mapped_regions);
@@ -881,10 +898,12 @@ namespace Kernel
child_exit_status->pgrp = forked->pgrp(); child_exit_status->pgrp = forked->pgrp();
ASSERT(this == &Process::current()); ASSERT(this == &Process::current());
// FIXME: this should be able to fail
Thread* thread = MUST(Thread::current().clone(forked, sp, ip)); MUST(forked->m_threads.push_back(thread));
forked->add_thread(thread); MUST(Processor::scheduler().add_thread(thread));
forked->register_to_scheduler();
process_deleter.disable();
thread_deleter.disable();
return forked->pid(); return forked->pid();
} }