Kernel: Rework syscall calling

I removed the intermediate function when calling syscalls. Now syscall
handler calls the current process automatically. Only exception is
sys_fork, since it needs a assembly trampoline for the new thread.
This commit is contained in:
Bananymous 2023-06-12 14:16:48 +03:00
parent ce55422a24
commit bf617036c7
6 changed files with 200 additions and 399 deletions

View File

@ -121,7 +121,7 @@ namespace IDT
if (tid && Kernel::Thread::current().is_userspace() && !Kernel::Thread::current().is_in_syscall())
{
auto message = BAN::String::formatted("{}, aborting\n", isr_exceptions[isr]);
(void)Kernel::Process::current().write(STDERR_FILENO, message.data(), message.size());
(void)Kernel::Process::current().sys_write(STDERR_FILENO, message.data(), message.size());
asm volatile("sti");
Kernel::Process::current().exit(1);
}

View File

@ -14,6 +14,7 @@
#include <kernel/Thread.h>
#include <sys/stat.h>
#include <termios.h>
namespace LibELF { class ELF; }
@ -46,60 +47,60 @@ namespace Kernel
void add_thread(Thread*);
void on_thread_exit(Thread&);
BAN::ErrorOr<void> set_termios(const termios&);
pid_t pid() const { return m_pid; }
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<long> sys_exit(int status);
int block_until_exit();
BAN::ErrorOr<pid_t> wait(pid_t pid, int* stat_loc, int options);
BAN::ErrorOr<long> sys_gettermios(::termios*);
BAN::ErrorOr<long> sys_settermios(const ::termios*);
BAN::ErrorOr<void> setenvp(char** envp);
BAN::ErrorOr<long> sys_fork(uintptr_t rsp, uintptr_t rip);
BAN::ErrorOr<long> sys_exec(BAN::StringView path, const char* const* argv, const char* const* envp);
BAN::ErrorOr<void> set_pwd(const char* path);
BAN::ErrorOr<char*> get_pwd(char* buffer, size_t size);
BAN::ErrorOr<long> sys_wait(pid_t pid, int* stat_loc, int options);
BAN::ErrorOr<long> sys_sleep(int seconds);
BAN::ErrorOr<void> set_uid(uid_t);
BAN::ErrorOr<void> set_gid(gid_t);
BAN::ErrorOr<void> set_euid(uid_t);
BAN::ErrorOr<void> set_egid(gid_t);
BAN::ErrorOr<void> set_reuid(uid_t, uid_t);
BAN::ErrorOr<void> set_regid(gid_t, gid_t);
BAN::ErrorOr<long> sys_setenvp(char** envp);
uid_t get_uid() const { return m_credentials.ruid(); }
gid_t get_gid() const { return m_credentials.rgid(); }
uid_t get_euid() const { return m_credentials.euid(); }
gid_t get_egid() const { return m_credentials.egid(); }
BAN::ErrorOr<long> sys_setpwd(const char* path);
BAN::ErrorOr<long> sys_getpwd(char* buffer, size_t size);
BAN::ErrorOr<int> open(BAN::StringView, int);
BAN::ErrorOr<int> openat(int, BAN::StringView, int);
BAN::ErrorOr<void> close(int fd);
BAN::ErrorOr<size_t> read(int fd, void* buffer, size_t count);
BAN::ErrorOr<size_t> write(int fd, const void* buffer, size_t count);
BAN::ErrorOr<void> creat(BAN::StringView name, mode_t);
BAN::ErrorOr<long> sys_setuid(uid_t);
BAN::ErrorOr<long> sys_setgid(gid_t);
BAN::ErrorOr<long> sys_seteuid(uid_t);
BAN::ErrorOr<long> sys_setegid(gid_t);
BAN::ErrorOr<long> sys_setreuid(uid_t, uid_t);
BAN::ErrorOr<long> sys_setregid(gid_t, gid_t);
BAN::ErrorOr<void> seek(int fd, off_t offset, int whence);
BAN::ErrorOr<off_t> tell(int fd);
BAN::ErrorOr<long> sys_getuid() const { return m_credentials.ruid(); }
BAN::ErrorOr<long> sys_getgid() const { return m_credentials.rgid(); }
BAN::ErrorOr<long> sys_geteuid() const { return m_credentials.euid(); }
BAN::ErrorOr<long> sys_getegid() const { return m_credentials.egid(); }
BAN::ErrorOr<void> fstat(int fd, struct stat*);
BAN::ErrorOr<void> stat(BAN::StringView path, struct stat*, int flags);
BAN::ErrorOr<long> sys_open(BAN::StringView, int);
BAN::ErrorOr<long> sys_openat(int, BAN::StringView, int);
BAN::ErrorOr<long> sys_close(int fd);
BAN::ErrorOr<long> sys_read(int fd, void* buffer, size_t count);
BAN::ErrorOr<long> sys_write(int fd, const void* buffer, size_t count);
BAN::ErrorOr<long> sys_creat(BAN::StringView name, mode_t);
BAN::ErrorOr<long> sys_seek(int fd, off_t offset, int whence);
BAN::ErrorOr<long> sys_tell(int fd);
BAN::ErrorOr<long> sys_fstat(int fd, struct stat*);
BAN::ErrorOr<long> sys_stat(BAN::StringView path, struct stat*, int flags);
BAN::ErrorOr<void> mount(BAN::StringView source, BAN::StringView target);
BAN::ErrorOr<void> read_next_directory_entries(int fd, DirectoryEntryList* buffer, size_t buffer_size);
BAN::ErrorOr<long> sys_read_dir_entries(int fd, DirectoryEntryList* buffer, size_t buffer_size);
BAN::ErrorOr<BAN::String> working_directory() const;
BAN::ErrorOr<void> set_working_directory(BAN::StringView);
BAN::ErrorOr<long> sys_alloc(size_t);
BAN::ErrorOr<long> sys_free(void*);
BAN::ErrorOr<long> sys_termid(char*) const;
TTY& tty() { ASSERT(m_tty); return *m_tty; }
BAN::ErrorOr<void*> allocate(size_t);
void free(void*);
void termid(char*) const;
static Process& current() { return Thread::current().process(); }
PageTable& page_table() { return m_page_table ? *m_page_table : PageTable::kernel(); }
@ -117,6 +118,8 @@ namespace Kernel
// Copy an elf file from the current page table to the processes own
void load_elf_to_memory(LibELF::ELF&);
int block_until_exit();
BAN::ErrorOr<BAN::String> absolute_path_of(BAN::StringView) const;
private:

View File

@ -37,15 +37,15 @@ namespace Kernel
BAN::ErrorOr<Font> Font::load(BAN::StringView path)
{
int fd = TRY(Process::current().open(path, O_RDONLY));
BAN::ScopeGuard _([fd] { MUST(Process::current().close(fd)); });
int fd = TRY(Process::current().sys_open(path, O_RDONLY));
BAN::ScopeGuard _([fd] { MUST(Process::current().sys_close(fd)); });
struct stat st;
TRY(Process::current().fstat(fd, &st));
TRY(Process::current().sys_fstat(fd, &st));
BAN::Vector<uint8_t> file_data;
TRY(file_data.resize(st.st_size));
TRY(Process::current().read(fd, file_data.data(), st.st_size));
TRY(Process::current().sys_read(fd, file_data.data(), st.st_size));
if (file_data.size() < 4)
return BAN::Error::from_error_code(ErrorCode::Font_FileTooSmall);

View File

@ -65,15 +65,15 @@ namespace Kernel
{
PageTableScope _(process->page_table());
argv = (char**)MUST(process->allocate(sizeof(char**) * 2));
argv[0] = (char*)MUST(process->allocate(path.size() + 1));
argv = (char**)MUST(process->sys_alloc(sizeof(char**) * 2));
argv[0] = (char*)MUST(process->sys_alloc(path.size() + 1));
memcpy(argv[0], path.data(), path.size());
argv[0][path.size()] = '\0';
argv[1] = nullptr;
BAN::StringView env1 = "PATH=/bin:/usr/bin"sv;
envp = (char**)MUST(process->allocate(sizeof(char**) * 2));
envp[0] = (char*)MUST(process->allocate(env1.size() + 1));
envp = (char**)MUST(process->sys_alloc(sizeof(char**) * 2));
envp[0] = (char*)MUST(process->sys_alloc(env1.size() + 1));
memcpy(envp[0], env1.data(), env1.size());
envp[0][env1.size()] = '\0';
envp[1] = nullptr;
@ -159,13 +159,40 @@ namespace Kernel
Scheduler::get().set_current_process_done();
}
BAN::ErrorOr<void> Process::set_termios(const termios& termios)
BAN::ErrorOr<long> Process::sys_exit(int status)
{
exit(status);
ASSERT_NOT_REACHED();
}
BAN::ErrorOr<long> Process::sys_gettermios(::termios* termios)
{
LockGuard _(m_lock);
if (m_tty == nullptr)
return BAN::Error::from_errno(ENOTTY);
m_tty->set_termios(termios);
return {};
Kernel::termios ktermios = m_tty->get_termios();
termios->c_lflag = 0;
if (ktermios.canonical)
termios->c_lflag |= ICANON;
if (ktermios.echo)
termios->c_lflag |= ECHO;
return 0;
}
BAN::ErrorOr<long> Process::sys_settermios(const ::termios* termios)
{
LockGuard _(m_lock);
if (m_tty == nullptr)
return BAN::Error::from_errno(ENOTTY);
Kernel::termios ktermios;
ktermios.echo = termios->c_lflag & ECHO;
ktermios.canonical = termios->c_lflag & ICANON;
m_tty->set_termios(ktermios);
return 0;
}
BAN::ErrorOr<BAN::UniqPtr<LibELF::ELF>> Process::load_elf_for_exec(const Credentials& credentials, BAN::StringView file_path, const BAN::String& cwd, const BAN::Vector<BAN::StringView>& path_env)
@ -241,7 +268,7 @@ namespace Kernel
return BAN::move(elf);
}
BAN::ErrorOr<Process*> Process::fork(uintptr_t rsp, uintptr_t rip)
BAN::ErrorOr<long> Process::sys_fork(uintptr_t rsp, uintptr_t rip)
{
Process* forked = create_process(m_credentials);
@ -271,10 +298,10 @@ namespace Kernel
register_process(forked);
return forked;
return forked->pid();
}
BAN::ErrorOr<void> Process::exec(BAN::StringView path, const char* const* argv, const char* const* envp)
BAN::ErrorOr<long> Process::sys_exec(BAN::StringView path, const char* const* argv, const char* const* envp)
{
BAN::Vector<BAN::String> str_argv;
for (int i = 0; argv && argv[i]; i++)
@ -289,7 +316,14 @@ namespace Kernel
path_env = TRY(BAN::StringView(envp[i]).substring(5).split(':'));
}
auto elf = TRY(load_elf_for_exec(m_credentials, path, TRY(working_directory()), path_env));
BAN::String working_directory;
{
LockGuard _(m_lock);
TRY(working_directory.append(m_working_directory));
}
auto elf = TRY(load_elf_for_exec(m_credentials, path, working_directory, path_env));
LockGuard lock_guard(m_lock);
@ -313,19 +347,19 @@ namespace Kernel
{
LockGuard _(page_table());
m_userspace_info.argv = (char**)MUST(allocate(sizeof(char**) * (str_argv.size() + 1)));
m_userspace_info.argv = (char**)MUST(sys_alloc(sizeof(char**) * (str_argv.size() + 1)));
for (size_t i = 0; i < str_argv.size(); i++)
{
m_userspace_info.argv[i] = (char*)MUST(allocate(str_argv[i].size() + 1));
m_userspace_info.argv[i] = (char*)MUST(sys_alloc(str_argv[i].size() + 1));
memcpy(m_userspace_info.argv[i], str_argv[i].data(), str_argv[i].size());
m_userspace_info.argv[i][str_argv[i].size()] = '\0';
}
m_userspace_info.argv[str_argv.size()] = nullptr;
m_userspace_info.envp = (char**)MUST(allocate(sizeof(char**) * (str_envp.size() + 1)));
m_userspace_info.envp = (char**)MUST(sys_alloc(sizeof(char**) * (str_envp.size() + 1)));
for (size_t i = 0; i < str_envp.size(); i++)
{
m_userspace_info.envp[i] = (char*)MUST(allocate(str_envp[i].size() + 1));
m_userspace_info.envp[i] = (char*)MUST(sys_alloc(str_envp[i].size() + 1));
memcpy(m_userspace_info.envp[i], str_envp[i].data(), str_envp[i].size());
m_userspace_info.envp[i][str_envp[i].size()] = '\0';
}
@ -370,7 +404,7 @@ namespace Kernel
return ret;
}
BAN::ErrorOr<pid_t> Process::wait(pid_t pid, int* stat_loc, int options)
BAN::ErrorOr<long> Process::sys_wait(pid_t pid, int* stat_loc, int options)
{
Process* target = nullptr;
@ -392,11 +426,17 @@ namespace Kernel
return ret;
}
BAN::ErrorOr<void> Process::setenvp(char** envp)
BAN::ErrorOr<long> Process::sys_sleep(int seconds)
{
PIT::sleep(seconds * 1000);
return 0;
}
BAN::ErrorOr<long> Process::sys_setenvp(char** envp)
{
LockGuard _(m_lock);
m_userspace_info.envp = envp;
return {};
return 0;
}
void Process::load_elf_to_memory(LibELF::ELF& elf)
@ -450,7 +490,7 @@ namespace Kernel
}
}
BAN::ErrorOr<int> Process::open(BAN::StringView path, int flags)
BAN::ErrorOr<long> Process::sys_open(BAN::StringView path, int flags)
{
if (flags & ~(O_RDONLY | O_WRONLY | O_NOFOLLOW | O_SEARCH))
return BAN::Error::from_errno(ENOTSUP);
@ -470,7 +510,7 @@ namespace Kernel
return fd;
}
BAN::ErrorOr<int> Process::openat(int fd, BAN::StringView path, int flags)
BAN::ErrorOr<long> Process::sys_openat(int fd, BAN::StringView path, int flags)
{
BAN::String absolute_path;
@ -483,19 +523,19 @@ namespace Kernel
TRY(absolute_path.push_back('/'));
TRY(absolute_path.append(path));
return open(absolute_path, flags);
return sys_open(absolute_path, flags);
}
BAN::ErrorOr<void> Process::close(int fd)
BAN::ErrorOr<long> Process::sys_close(int fd)
{
LockGuard _(m_lock);
TRY(validate_fd(fd));
auto& open_file_description = this->open_file_description(fd);
open_file_description.inode = nullptr;
return {};
return 0;
}
BAN::ErrorOr<size_t> Process::read(int fd, void* buffer, size_t count)
BAN::ErrorOr<long> Process::sys_read(int fd, void* buffer, size_t count)
{
OpenFileDescription open_fd_copy;
@ -519,7 +559,7 @@ namespace Kernel
return nread;
}
BAN::ErrorOr<size_t> Process::write(int fd, const void* buffer, size_t count)
BAN::ErrorOr<long> Process::sys_write(int fd, const void* buffer, size_t count)
{
OpenFileDescription open_fd_copy;
@ -543,7 +583,7 @@ namespace Kernel
return nwrite;
}
BAN::ErrorOr<void> Process::seek(int fd, off_t offset, int whence)
BAN::ErrorOr<long> Process::sys_seek(int fd, off_t offset, int whence)
{
LockGuard _(m_lock);
TRY(validate_fd(fd));
@ -571,17 +611,17 @@ namespace Kernel
return BAN::Error::from_errno(EINVAL);
open_fd.offset = new_offset;
return {};
return 0;
}
BAN::ErrorOr<off_t> Process::tell(int fd)
BAN::ErrorOr<long> Process::sys_tell(int fd)
{
LockGuard _(m_lock);
TRY(validate_fd(fd));
return open_file_description(fd).offset;
}
BAN::ErrorOr<void> Process::creat(BAN::StringView path, mode_t mode)
BAN::ErrorOr<long> Process::sys_creat(BAN::StringView path, mode_t mode)
{
auto absolute_path = TRY(absolute_path_of(path));
@ -596,7 +636,7 @@ namespace Kernel
auto parent_file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, directory, O_WRONLY));
TRY(parent_file.inode->create_file(file_name, mode));
return {};
return 0;
}
BAN::ErrorOr<void> Process::mount(BAN::StringView source, BAN::StringView target)
@ -611,7 +651,7 @@ namespace Kernel
return {};
}
BAN::ErrorOr<void> Process::fstat(int fd, struct stat* out)
BAN::ErrorOr<long> Process::sys_fstat(int fd, struct stat* out)
{
OpenFileDescription open_fd_copy;
@ -635,18 +675,18 @@ namespace Kernel
out->st_blksize = open_fd_copy.inode->blksize();
out->st_blocks = open_fd_copy.inode->blocks();
return {};
return 0;
}
BAN::ErrorOr<void> Process::stat(BAN::StringView path, struct stat* out, int flags)
BAN::ErrorOr<long> Process::sys_stat(BAN::StringView path, struct stat* out, int flags)
{
int fd = TRY(open(path, flags));
auto ret = fstat(fd, out);
MUST(close(fd));
int fd = TRY(sys_open(path, flags));
auto ret = sys_fstat(fd, out);
MUST(sys_close(fd));
return ret;
}
BAN::ErrorOr<void> Process::read_next_directory_entries(int fd, DirectoryEntryList* list, size_t list_size)
BAN::ErrorOr<long> Process::sys_read_dir_entries(int fd, DirectoryEntryList* list, size_t list_size)
{
OpenFileDescription open_fd_copy;
@ -664,10 +704,10 @@ namespace Kernel
open_file_description(fd).offset = open_fd_copy.offset + 1;
}
return {};
return 0;
}
BAN::ErrorOr<void> Process::set_pwd(const char* path)
BAN::ErrorOr<long> Process::sys_setpwd(const char* path)
{
BAN::String absolute_path;
@ -683,10 +723,10 @@ namespace Kernel
LockGuard _(m_lock);
m_working_directory = BAN::move(file.canonical_path);
return {};
return 0;
}
BAN::ErrorOr<char*> Process::get_pwd(char* buffer, size_t size)
BAN::ErrorOr<long> Process::sys_getpwd(char* buffer, size_t size)
{
LockGuard _(m_lock);
@ -696,31 +736,7 @@ namespace Kernel
memcpy(buffer, m_working_directory.data(), m_working_directory.size());
buffer[m_working_directory.size()] = '\0';
return buffer;
}
BAN::ErrorOr<BAN::String> Process::working_directory() const
{
BAN::String result;
LockGuard _(m_lock);
TRY(result.append(m_working_directory));
return result;
}
BAN::ErrorOr<void> Process::set_working_directory(BAN::StringView path)
{
BAN::String absolute_path = TRY(absolute_path_of(path));
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, O_SEARCH));
if (!file.inode->mode().ifdir())
return BAN::Error::from_errno(ENOTDIR);
LockGuard _(m_lock);
m_working_directory = BAN::move(file.canonical_path);
return {};
return (long)buffer;
}
static constexpr size_t allocator_size_for_allocation(size_t value)
@ -738,7 +754,7 @@ namespace Kernel
}
}
BAN::ErrorOr<void*> Process::allocate(size_t bytes)
BAN::ErrorOr<long> Process::sys_alloc(size_t bytes)
{
vaddr_t address = 0;
@ -782,10 +798,10 @@ namespace Kernel
if (address == 0)
return BAN::Error::from_errno(ENOMEM);
return (void*)address;
return address;
}
void Process::free(void* ptr)
BAN::ErrorOr<long> Process::sys_free(void* ptr)
{
LockGuard _(m_lock);
@ -798,26 +814,28 @@ namespace Kernel
// remove allocators when we have low memory... ?
if (allocator->allocations() == 0)
m_fixed_width_allocators.remove(i);
return;
return 0;
}
}
if (m_general_allocator && m_general_allocator->deallocate((vaddr_t)ptr))
return;
return 0;
dwarnln("free called on pointer that was not allocated");
dwarnln("free called on pointer that was not allocated");
return BAN::Error::from_errno(EINVAL);
}
void Process::termid(char* buffer) const
BAN::ErrorOr<long> Process::sys_termid(char* buffer) const
{
LockGuard _(m_lock);
if (m_tty == nullptr)
buffer[0] = '\0';
strcpy(buffer, "/dev/");
strcpy(buffer + 5, m_tty->name().data());
return 0;
}
BAN::ErrorOr<void> Process::set_uid(uid_t uid)
BAN::ErrorOr<long> Process::sys_setuid(uid_t uid)
{
if (uid < 0 || uid >= 1'000'000'000)
return BAN::Error::from_errno(EINVAL);
@ -831,7 +849,7 @@ namespace Kernel
m_credentials.set_euid(uid);
m_credentials.set_ruid(uid);
m_credentials.set_suid(uid);
return {};
return 0;
}
// If the process does not have appropriate privileges, but uid is equal to the real user ID or the saved set-user-ID,
@ -839,13 +857,13 @@ namespace Kernel
if (uid == m_credentials.ruid() || uid == m_credentials.suid())
{
m_credentials.set_euid(uid);
return {};
return 0;
}
return BAN::Error::from_errno(EPERM);
}
BAN::ErrorOr<void> Process::set_gid(gid_t gid)
BAN::ErrorOr<long> Process::sys_setgid(gid_t gid)
{
if (gid < 0 || gid >= 1'000'000'000)
return BAN::Error::from_errno(EINVAL);
@ -859,7 +877,7 @@ namespace Kernel
m_credentials.set_egid(gid);
m_credentials.set_rgid(gid);
m_credentials.set_sgid(gid);
return {};
return 0;
}
// If the process does not have appropriate privileges, but gid is equal to the real group ID or the saved set-group-ID,
@ -867,13 +885,13 @@ namespace Kernel
if (gid == m_credentials.rgid() || gid == m_credentials.sgid())
{
m_credentials.set_egid(gid);
return {};
return 0;
}
return BAN::Error::from_errno(EPERM);
}
BAN::ErrorOr<void> Process::set_euid(uid_t uid)
BAN::ErrorOr<long> Process::sys_seteuid(uid_t uid)
{
if (uid < 0 || uid >= 1'000'000'000)
return BAN::Error::from_errno(EINVAL);
@ -885,13 +903,13 @@ namespace Kernel
if (uid == m_credentials.ruid() || uid == m_credentials.suid() || m_credentials.is_superuser())
{
m_credentials.set_euid(uid);
return {};
return 0;
}
return BAN::Error::from_errno(EPERM);
}
BAN::ErrorOr<void> Process::set_egid(gid_t gid)
BAN::ErrorOr<long> Process::sys_setegid(gid_t gid)
{
if (gid < 0 || gid >= 1'000'000'000)
return BAN::Error::from_errno(EINVAL);
@ -904,16 +922,16 @@ namespace Kernel
if (gid == m_credentials.rgid() || gid == m_credentials.sgid() || m_credentials.is_superuser())
{
m_credentials.set_egid(gid);
return {};
return 0;
}
return BAN::Error::from_errno(EPERM);
}
BAN::ErrorOr<void> Process::set_reuid(uid_t ruid, uid_t euid)
BAN::ErrorOr<long> Process::sys_setreuid(uid_t ruid, uid_t euid)
{
if (ruid == -1 && euid == -1)
return {};
return 0;
if (ruid < -1 || ruid >= 1'000'000'000)
return BAN::Error::from_errno(EINVAL);
@ -951,13 +969,13 @@ namespace Kernel
if (euid != -1)
m_credentials.set_euid(euid);
return {};
return 0;
}
BAN::ErrorOr<void> Process::set_regid(gid_t rgid, gid_t egid)
BAN::ErrorOr<long> Process::sys_setregid(gid_t rgid, gid_t egid)
{
if (rgid == -1 && egid == -1)
return {};
return 0;
if (rgid < -1 || rgid >= 1'000'000'000)
return BAN::Error::from_errno(EINVAL);
@ -995,22 +1013,29 @@ namespace Kernel
if (egid != -1)
m_credentials.set_egid(egid);
return {};
return 0;
}
BAN::ErrorOr<BAN::String> Process::absolute_path_of(BAN::StringView path) const
{
if (path.empty())
return working_directory();
if (path.empty() || path == "."sv)
{
LockGuard _(m_lock);
return m_working_directory;
}
BAN::String absolute_path;
if (path.front() != '/')
{
LockGuard _(m_lock);
TRY(absolute_path.append(m_working_directory));
}
if (!absolute_path.empty() && absolute_path.back() != '/')
TRY(absolute_path.push_back('/'));
TRY(absolute_path.append(path));
return absolute_path;
}

View File

@ -7,243 +7,14 @@
namespace Kernel
{
void sys_exit(int status)
{
Process::current().exit(status);
}
long sys_read(int fd, void* buffer, size_t size)
{
auto res = Process::current().read(fd, buffer, size);
if (res.is_error())
return -res.error().get_error_code();
return res.value();
}
long sys_write(int fd, const void* buffer, size_t size)
{
auto res = Process::current().write(fd, buffer, size);
if (res.is_error())
return -res.error().get_error_code();
return res.value();
}
int sys_close(int fd)
{
auto res = Process::current().close(fd);
if (res.is_error())
return -res.error().get_error_code();
return 0;
}
void sys_termid(char* buffer)
{
Process::current().termid(buffer);
}
int sys_open(const char* path, int oflags)
{
auto res = Process::current().open(path, oflags);
if (res.is_error())
return -res.error().get_error_code();
return res.value();
}
int sys_openat(int fd, const char* path, int oflags)
{
auto res = Process::current().openat(fd, path, oflags);
if (res.is_error())
return -res.error().get_error_code();
return res.value();
}
long sys_alloc(size_t bytes)
{
auto res = Process::current().allocate(bytes);
if (res.is_error())
return -res.error().get_error_code();
return (long)res.value();
}
void sys_free(void* ptr)
{
Process::current().free(ptr);
}
long sys_seek(int fd, long offset, int whence)
{
auto res = Process::current().seek(fd, offset, whence);
if (res.is_error())
return -res.error().get_error_code();
return 0;
}
long sys_tell(int fd)
{
auto res = Process::current().tell(fd);
if (res.is_error())
return -res.error().get_error_code();
return res.value();
}
long sys_get_termios(::termios* termios)
{
auto current = Process::current().tty().get_termios();
memset(termios, 0, sizeof(::termios));
if (current.canonical)
termios->c_lflag |= ICANON;
if (current.echo)
termios->c_lflag |= ECHO;
return 0;
}
long sys_set_termios(const ::termios* termios)
{
Kernel::termios new_termios;
new_termios.canonical = termios->c_lflag & ICANON;
new_termios.echo = termios->c_lflag & ECHO;
Process::current().tty().set_termios(new_termios);
return 0;
}
extern "C" long sys_fork(uintptr_t rsp, uintptr_t rip)
{
auto ret = Process::current().fork(rsp, rip);
if (ret.is_error())
return -ret.error().get_error_code();
return ret.value()->pid();
}
long sys_exec(const char* pathname, const char* const* argv, const char* const* envp)
{
auto ret = Process::current().exec(pathname, argv, envp);
if (ret.is_error())
return -ret.error().get_error_code();
ASSERT_NOT_REACHED();
}
long sys_sleep(unsigned int seconds)
{
PIT::sleep(seconds * 1000);
return 0;
}
long sys_wait(pid_t pid, int* stat_loc, int options)
{
auto ret = Process::current().wait(pid, stat_loc, options);
auto ret = Process::current().sys_fork(rsp, rip);
if (ret.is_error())
return -ret.error().get_error_code();
return ret.value();
}
long sys_fstat(int fd, struct stat* buf)
{
auto ret = Process::current().fstat(fd, buf);
if (ret.is_error())
return -ret.error().get_error_code();
return 0;
}
long sys_setenvp(char** envp)
{
auto ret = Process::current().setenvp(envp);
if (ret.is_error())
return -ret.error().get_error_code();
return 0;
}
long sys_read_dir_entries(int fd, API::DirectoryEntryList* buffer, size_t buffer_size)
{
auto ret = Process::current().read_next_directory_entries(fd, buffer, buffer_size);
if (ret.is_error())
return -ret.error().get_error_code();
return 0;
}
long sys_set_uid(uid_t uid)
{
auto ret = Process::current().set_uid(uid);
if (ret.is_error())
return -ret.error().get_error_code();
return 0;
}
long sys_set_gid(gid_t gid)
{
auto ret = Process::current().set_gid(gid);
if (ret.is_error())
return -ret.error().get_error_code();
return 0;
}
long sys_set_euid(uid_t uid)
{
auto ret = Process::current().set_euid(uid);
if (ret.is_error())
return -ret.error().get_error_code();
return 0;
}
long sys_set_egid(gid_t gid)
{
auto ret = Process::current().set_egid(gid);
if (ret.is_error())
return -ret.error().get_error_code();
return 0;
}
long sys_set_reuid(uid_t ruid, uid_t euid)
{
auto ret = Process::current().set_reuid(ruid, euid);
if (ret.is_error())
return -ret.error().get_error_code();
return 0;
}
long sys_set_regid(gid_t rgid, gid_t egid)
{
auto ret = Process::current().set_regid(rgid, egid);
if (ret.is_error())
return -ret.error().get_error_code();
return 0;
}
long sys_get_uid()
{
return Process::current().get_uid();
}
long sys_get_gid()
{
return Process::current().get_gid();
}
long sys_get_euid()
{
return Process::current().get_euid();
}
long sys_get_egid()
{
return Process::current().get_egid();
}
long sys_get_pwd(char* buffer, size_t size)
{
auto ret = Process::current().get_pwd(buffer, size);
if (ret.is_error())
return -ret.error().get_error_code();
return (long)ret.value();
}
long sys_set_pwd(const char* path)
{
auto ret = Process::current().set_pwd(path);
if (ret.is_error())
return -ret.error().get_error_code();
return 0;
}
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)
@ -258,108 +29,108 @@ namespace Kernel
(void)arg4;
(void)arg5;
long ret = 0;
BAN::ErrorOr<long> ret = BAN::Error::from_errno(ENOSYS);
switch (syscall)
{
case SYS_EXIT:
sys_exit((int)arg1);
ret = Process::current().sys_exit((int)arg1);
break;
case SYS_READ:
ret = sys_read((int)arg1, (void*)arg2, (size_t)arg3);
ret = Process::current().sys_read((int)arg1, (void*)arg2, (size_t)arg3);
break;
case SYS_WRITE:
ret = sys_write((int)arg1, (const void*)arg2, (size_t)arg3);
ret = Process::current().sys_write((int)arg1, (const void*)arg2, (size_t)arg3);
break;
case SYS_TERMID:
sys_termid((char*)arg1);
ret = Process::current().sys_termid((char*)arg1);
break;
case SYS_CLOSE:
ret = sys_close((int)arg1);
ret = Process::current().sys_close((int)arg1);
break;
case SYS_OPEN:
ret = sys_open((const char*)arg1, (int)arg2);
ret = Process::current().sys_open((const char*)arg1, (int)arg2);
break;
case SYS_OPENAT:
ret = sys_openat((int)arg1, (const char*)arg2, (int)arg3);
ret = Process::current().sys_openat((int)arg1, (const char*)arg2, (int)arg3);
break;
case SYS_ALLOC:
ret = sys_alloc((size_t)arg1);
ret = Process::current().sys_alloc((size_t)arg1);
break;
case SYS_FREE:
sys_free((void*)arg1);
ret = Process::current().sys_free((void*)arg1);
break;
case SYS_SEEK:
ret = sys_seek((int)arg1, (long)arg2, (int)arg3);
ret = Process::current().sys_seek((int)arg1, (long)arg2, (int)arg3);
break;
case SYS_TELL:
ret = sys_tell((int)arg1);
ret = Process::current().sys_tell((int)arg1);
break;
case SYS_GET_TERMIOS:
ret = sys_get_termios((::termios*)arg1);
ret = Process::current().sys_gettermios((::termios*)arg1);
break;
case SYS_SET_TERMIOS:
ret = sys_set_termios((const ::termios*)arg1);
ret = Process::current().sys_settermios((const ::termios*)arg1);
break;
case SYS_FORK:
ret = sys_fork_trampoline();
break;
case SYS_EXEC:
ret = sys_exec((const char*)arg1, (const char* const*)arg2, (const char* const*)arg3);
ret = Process::current().sys_exec((const char*)arg1, (const char* const*)arg2, (const char* const*)arg3);
break;
case SYS_SLEEP:
ret = sys_sleep((unsigned int)arg1);
ret = Process::current().sys_sleep((unsigned int)arg1);
break;
case SYS_WAIT:
ret = sys_wait((pid_t)arg1, (int*)arg2, (int)arg3);
ret = Process::current().sys_wait((pid_t)arg1, (int*)arg2, (int)arg3);
break;
case SYS_FSTAT:
ret = sys_fstat((int)arg1, (struct stat*)arg2);
ret = Process::current().sys_fstat((int)arg1, (struct stat*)arg2);
break;
case SYS_SETENVP:
ret = sys_setenvp((char**)arg1);
ret = Process::current().sys_setenvp((char**)arg1);
break;
case SYS_READ_DIR_ENTRIES:
ret = sys_read_dir_entries((int)arg1, (API::DirectoryEntryList*)arg2, (size_t)arg3);
ret = Process::current().sys_read_dir_entries((int)arg1, (API::DirectoryEntryList*)arg2, (size_t)arg3);
break;
case SYS_SET_UID:
ret = sys_set_uid((uid_t)arg1);
ret = Process::current().sys_setuid((uid_t)arg1);
break;
case SYS_SET_GID:
ret = sys_set_gid((gid_t)arg1);
ret = Process::current().sys_setgid((gid_t)arg1);
break;
case SYS_SET_EUID:
ret = sys_set_euid((uid_t)arg1);
ret = Process::current().sys_seteuid((uid_t)arg1);
break;
case SYS_SET_EGID:
ret = sys_set_egid((gid_t)arg1);
ret = Process::current().sys_setegid((gid_t)arg1);
break;
case SYS_SET_REUID:
ret = sys_set_reuid((uid_t)arg1, (uid_t)arg2);
ret = Process::current().sys_setreuid((uid_t)arg1, (uid_t)arg2);
break;
case SYS_SET_REGID:
ret = sys_set_regid((gid_t)arg1, (gid_t)arg2);
ret = Process::current().sys_setregid((gid_t)arg1, (gid_t)arg2);
break;
case SYS_GET_UID:
ret = sys_get_uid();
ret = Process::current().sys_getuid();
break;
case SYS_GET_GID:
ret = sys_get_gid();
ret = Process::current().sys_getgid();
break;
case SYS_GET_EUID:
ret = sys_get_euid();
ret = Process::current().sys_geteuid();
break;
case SYS_GET_EGID:
ret = sys_get_egid();
ret = Process::current().sys_getegid();
break;
case SYS_GET_PWD:
ret = sys_get_pwd((char*)arg1, (size_t)arg2);
ret = Process::current().sys_getpwd((char*)arg1, (size_t)arg2);
break;
case SYS_SET_PWD:
ret = sys_set_pwd((const char*)arg1);
ret = Process::current().sys_setpwd((const char*)arg1);
break;
default:
dwarnln("Unknown syscall {}", syscall);
ret = -ENOSYS;
break;
}
@ -367,7 +138,9 @@ namespace Kernel
Thread::current().set_in_syscall(false);
return ret;
if (ret.is_error())
return -ret.error().get_error_code();
return ret.value();
}
}

View File

@ -62,11 +62,11 @@ namespace Kernel
s_input_process = Process::create_kernel(
[](void*)
{
int fd = MUST(Process::current().open("/dev/input0"sv, O_RDONLY));
int fd = MUST(Process::current().sys_open("/dev/input0"sv, O_RDONLY));
while (true)
{
Input::KeyEvent event;
ASSERT(MUST(Process::current().read(fd, &event, sizeof(event))) == sizeof(event));
ASSERT(MUST(Process::current().sys_read(fd, &event, sizeof(event))) == sizeof(event));
TTY::current()->on_key(event);
}
}, nullptr