forked from Bananymous/banan-os
parent
94d2090777
commit
b68d5a5833
|
@ -51,6 +51,9 @@ namespace Kernel
|
||||||
BAN::ErrorOr<Process*> fork(uintptr_t rsp, uintptr_t rip);
|
BAN::ErrorOr<Process*> fork(uintptr_t rsp, uintptr_t rip);
|
||||||
BAN::ErrorOr<void> exec(BAN::StringView path, const char* const* argv, const char* const* envp);
|
BAN::ErrorOr<void> exec(BAN::StringView path, const char* const* argv, const char* const* envp);
|
||||||
|
|
||||||
|
int block_until_exit();
|
||||||
|
BAN::ErrorOr<pid_t> wait(pid_t pid, int* stat_loc, int options);
|
||||||
|
|
||||||
BAN::ErrorOr<int> open(BAN::StringView, int);
|
BAN::ErrorOr<int> open(BAN::StringView, int);
|
||||||
BAN::ErrorOr<void> close(int fd);
|
BAN::ErrorOr<void> close(int fd);
|
||||||
BAN::ErrorOr<size_t> read(int fd, void* buffer, size_t count);
|
BAN::ErrorOr<size_t> read(int fd, void* buffer, size_t count);
|
||||||
|
@ -105,6 +108,15 @@ namespace Kernel
|
||||||
OpenFileDescription& open_file_description(int);
|
OpenFileDescription& open_file_description(int);
|
||||||
BAN::ErrorOr<int> get_free_fd();
|
BAN::ErrorOr<int> get_free_fd();
|
||||||
|
|
||||||
|
|
||||||
|
struct ExitStatus
|
||||||
|
{
|
||||||
|
Semaphore semaphore;
|
||||||
|
int exit_code { 0 };
|
||||||
|
bool exited { false };
|
||||||
|
int waiting { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
BAN::Vector<OpenFileDescription> m_open_files;
|
BAN::Vector<OpenFileDescription> m_open_files;
|
||||||
BAN::Vector<VirtualRange*> m_mapped_ranges;
|
BAN::Vector<VirtualRange*> m_mapped_ranges;
|
||||||
|
|
||||||
|
@ -118,6 +130,7 @@ namespace Kernel
|
||||||
BAN::UniqPtr<GeneralAllocator> m_general_allocator;
|
BAN::UniqPtr<GeneralAllocator> m_general_allocator;
|
||||||
|
|
||||||
userspace_entry_t m_userspace_entry;
|
userspace_entry_t m_userspace_entry;
|
||||||
|
ExitStatus m_exit_status;
|
||||||
|
|
||||||
BAN::UniqPtr<PageTable> m_page_table;
|
BAN::UniqPtr<PageTable> m_page_table;
|
||||||
TTY* m_tty { nullptr };
|
TTY* m_tty { nullptr };
|
||||||
|
|
|
@ -117,6 +117,15 @@ namespace Kernel
|
||||||
void Process::exit()
|
void Process::exit()
|
||||||
{
|
{
|
||||||
m_lock.lock();
|
m_lock.lock();
|
||||||
|
m_exit_status.exited = true;
|
||||||
|
while (m_exit_status.waiting > 0)
|
||||||
|
{
|
||||||
|
m_exit_status.semaphore.unblock();
|
||||||
|
m_lock.unlock();
|
||||||
|
// TODO: add proper software reschedule
|
||||||
|
Scheduler::get().set_current_thread_sleeping(0);
|
||||||
|
}
|
||||||
|
m_lock.lock();
|
||||||
|
|
||||||
m_threads.clear();
|
m_threads.clear();
|
||||||
for (auto& open_fd : m_open_files)
|
for (auto& open_fd : m_open_files)
|
||||||
|
@ -249,6 +258,52 @@ namespace Kernel
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Process::block_until_exit()
|
||||||
|
{
|
||||||
|
ASSERT(s_process_lock.is_locked());
|
||||||
|
ASSERT(this != &Process::current());
|
||||||
|
|
||||||
|
s_process_lock.unlock();
|
||||||
|
|
||||||
|
m_lock.lock();
|
||||||
|
m_exit_status.waiting++;
|
||||||
|
while (!m_exit_status.exited)
|
||||||
|
{
|
||||||
|
m_lock.unlock();
|
||||||
|
m_exit_status.semaphore.block();
|
||||||
|
m_lock.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = m_exit_status.exit_code;
|
||||||
|
m_exit_status.waiting--;
|
||||||
|
m_lock.unlock();
|
||||||
|
|
||||||
|
s_process_lock.lock();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<pid_t> Process::wait(pid_t pid, int* stat_loc, int options)
|
||||||
|
{
|
||||||
|
Process* target = nullptr;
|
||||||
|
|
||||||
|
// FIXME: support options
|
||||||
|
if (options)
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
|
LockGuard _(s_process_lock);
|
||||||
|
for (auto* process : s_processes)
|
||||||
|
if (process->pid() == pid)
|
||||||
|
target = process;
|
||||||
|
|
||||||
|
if (target == nullptr)
|
||||||
|
return BAN::Error::from_errno(ECHILD);
|
||||||
|
|
||||||
|
pid_t ret = target->pid();
|
||||||
|
*stat_loc = target->block_until_exit();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void Process::load_elf(LibELF::ELF& elf)
|
void Process::load_elf(LibELF::ELF& elf)
|
||||||
{
|
{
|
||||||
|
|
|
@ -120,6 +120,14 @@ namespace Kernel
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long sys_wait(pid_t pid, int* stat_loc, int options)
|
||||||
|
{
|
||||||
|
auto ret = Process::current().wait(pid, stat_loc, options);
|
||||||
|
if (ret.is_error())
|
||||||
|
return -ret.error().get_error_code();
|
||||||
|
return ret.value();
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" long sys_fork_trampoline();
|
extern "C" long sys_fork_trampoline();
|
||||||
|
|
||||||
extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5)
|
extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5)
|
||||||
|
@ -182,6 +190,9 @@ namespace Kernel
|
||||||
case SYS_EXEC:
|
case SYS_EXEC:
|
||||||
ret = sys_exec((const char*)arg1, (const char* const*)arg2, (const char* const*)arg3);
|
ret = sys_exec((const char*)arg1, (const char* const*)arg2, (const char* const*)arg3);
|
||||||
break;
|
break;
|
||||||
|
case SYS_WAIT:
|
||||||
|
ret = sys_wait((pid_t)arg1, (int*)arg2, (int)arg3);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Kernel::panic("Unknown syscall {}", syscall);
|
Kernel::panic("Unknown syscall {}", syscall);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue