2023-03-13 15:32:46 +02:00
|
|
|
#include <kernel/Debug.h>
|
2023-04-12 17:51:36 +03:00
|
|
|
#include <kernel/Process.h>
|
2023-03-13 15:32:46 +02:00
|
|
|
#include <kernel/Syscall.h>
|
|
|
|
|
2023-05-16 19:22:10 +03:00
|
|
|
#include <termios.h>
|
|
|
|
|
2023-03-13 15:32:46 +02:00
|
|
|
namespace Kernel
|
|
|
|
{
|
|
|
|
|
2023-06-10 17:31:56 +03:00
|
|
|
void sys_exit(int status)
|
2023-03-13 15:32:46 +02:00
|
|
|
{
|
2023-06-10 17:31:56 +03:00
|
|
|
Process::current().exit(status);
|
2023-04-12 17:51:36 +03:00
|
|
|
}
|
|
|
|
|
2023-05-16 14:14:47 +03:00
|
|
|
long sys_read(int fd, void* buffer, size_t size)
|
2023-04-12 17:51:36 +03:00
|
|
|
{
|
2023-05-16 14:14:47 +03:00
|
|
|
auto res = Process::current().read(fd, buffer, size);
|
2023-04-12 17:51:36 +03:00
|
|
|
if (res.is_error())
|
2023-04-23 14:32:37 +03:00
|
|
|
return -res.error().get_error_code();
|
2023-04-21 10:40:24 +03:00
|
|
|
return res.value();
|
2023-03-13 15:32:46 +02:00
|
|
|
}
|
|
|
|
|
2023-05-16 14:14:47 +03:00
|
|
|
long sys_write(int fd, const void* buffer, size_t size)
|
2023-03-13 15:32:46 +02:00
|
|
|
{
|
2023-05-16 14:14:47 +03:00
|
|
|
auto res = Process::current().write(fd, buffer, size);
|
2023-04-12 17:51:36 +03:00
|
|
|
if (res.is_error())
|
2023-04-23 14:32:37 +03:00
|
|
|
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();
|
2023-04-21 10:40:24 +03:00
|
|
|
return res.value();
|
2023-03-13 15:32:46 +02:00
|
|
|
}
|
2023-06-11 03:27:56 +03:00
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
2023-03-13 15:32:46 +02:00
|
|
|
|
2023-05-06 18:10:38 +03:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-05-07 01:21:50 +03:00
|
|
|
void sys_free(void* ptr)
|
|
|
|
{
|
|
|
|
Process::current().free(ptr);
|
|
|
|
}
|
|
|
|
|
2023-05-16 14:14:47 +03:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-05-16 19:22:10 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-05-28 18:08:26 +03:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-05-31 20:57:33 +03:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-06-11 03:28:43 +03:00
|
|
|
long sys_sleep(unsigned int seconds)
|
|
|
|
{
|
|
|
|
PIT::sleep(seconds * 1000);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-06-04 17:57:24 +03:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-06-11 00:54:04 +03:00
|
|
|
long sys_fstat(int fd, struct stat* buf)
|
2023-06-05 14:36:17 +03:00
|
|
|
{
|
2023-06-11 00:54:04 +03:00
|
|
|
auto ret = Process::current().fstat(fd, buf);
|
2023-06-05 14:36:17 +03:00
|
|
|
if (ret.is_error())
|
|
|
|
return -ret.error().get_error_code();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-06-05 22:43:26 +03:00
|
|
|
long sys_setenvp(char** envp)
|
|
|
|
{
|
|
|
|
auto ret = Process::current().setenvp(envp);
|
|
|
|
if (ret.is_error())
|
|
|
|
return -ret.error().get_error_code();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-06-11 00:18:08 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-06-11 22:15:35 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-06-11 22:27:53 +03:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-06-12 01:24:46 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-05-28 18:08:26 +03:00
|
|
|
extern "C" long sys_fork_trampoline();
|
|
|
|
|
2023-05-09 20:31:22 +03:00
|
|
|
extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5)
|
2023-03-13 15:32:46 +02:00
|
|
|
{
|
2023-04-21 10:40:24 +03:00
|
|
|
Thread::current().set_in_syscall(true);
|
2023-03-13 15:32:46 +02:00
|
|
|
|
2023-04-21 10:40:24 +03:00
|
|
|
asm volatile("sti");
|
|
|
|
|
2023-05-16 14:14:47 +03:00
|
|
|
(void)arg1;
|
|
|
|
(void)arg2;
|
|
|
|
(void)arg3;
|
|
|
|
(void)arg4;
|
2023-05-09 20:31:22 +03:00
|
|
|
(void)arg5;
|
|
|
|
|
2023-04-21 10:40:24 +03:00
|
|
|
long ret = 0;
|
2023-03-13 15:32:46 +02:00
|
|
|
switch (syscall)
|
|
|
|
{
|
2023-04-12 17:51:36 +03:00
|
|
|
case SYS_EXIT:
|
2023-06-10 17:31:56 +03:00
|
|
|
sys_exit((int)arg1);
|
2023-04-12 17:51:36 +03:00
|
|
|
break;
|
|
|
|
case SYS_READ:
|
2023-05-16 14:14:47 +03:00
|
|
|
ret = sys_read((int)arg1, (void*)arg2, (size_t)arg3);
|
2023-03-13 15:32:46 +02:00
|
|
|
break;
|
2023-04-12 17:51:36 +03:00
|
|
|
case SYS_WRITE:
|
2023-05-16 14:14:47 +03:00
|
|
|
ret = sys_write((int)arg1, (const void*)arg2, (size_t)arg3);
|
2023-03-13 15:32:46 +02:00
|
|
|
break;
|
2023-04-23 14:32:37 +03:00
|
|
|
case SYS_TERMID:
|
|
|
|
sys_termid((char*)arg1);
|
|
|
|
break;
|
|
|
|
case SYS_CLOSE:
|
2023-05-09 20:31:22 +03:00
|
|
|
ret = sys_close((int)arg1);
|
2023-03-13 15:32:46 +02:00
|
|
|
break;
|
2023-04-23 14:32:37 +03:00
|
|
|
case SYS_OPEN:
|
2023-05-09 20:31:22 +03:00
|
|
|
ret = sys_open((const char*)arg1, (int)arg2);
|
2023-04-23 14:32:37 +03:00
|
|
|
break;
|
2023-06-11 03:27:56 +03:00
|
|
|
case SYS_OPENAT:
|
|
|
|
ret = sys_openat((int)arg1, (const char*)arg2, (int)arg3);
|
|
|
|
break;
|
2023-05-06 18:10:38 +03:00
|
|
|
case SYS_ALLOC:
|
|
|
|
ret = sys_alloc((size_t)arg1);
|
|
|
|
break;
|
2023-05-07 01:21:50 +03:00
|
|
|
case SYS_FREE:
|
2023-05-09 20:31:22 +03:00
|
|
|
sys_free((void*)arg1);
|
2023-05-07 01:21:50 +03:00
|
|
|
break;
|
2023-05-16 14:14:47 +03:00
|
|
|
case SYS_SEEK:
|
|
|
|
ret = sys_seek((int)arg1, (long)arg2, (int)arg3);
|
|
|
|
break;
|
|
|
|
case SYS_TELL:
|
|
|
|
ret = sys_tell((int)arg1);
|
|
|
|
break;
|
2023-05-16 19:22:10 +03:00
|
|
|
case SYS_GET_TERMIOS:
|
|
|
|
ret = sys_get_termios((::termios*)arg1);
|
|
|
|
break;
|
|
|
|
case SYS_SET_TERMIOS:
|
|
|
|
ret = sys_set_termios((const ::termios*)arg1);
|
|
|
|
break;
|
2023-05-28 18:08:26 +03:00
|
|
|
case SYS_FORK:
|
|
|
|
ret = sys_fork_trampoline();
|
|
|
|
break;
|
2023-05-31 20:57:33 +03:00
|
|
|
case SYS_EXEC:
|
|
|
|
ret = sys_exec((const char*)arg1, (const char* const*)arg2, (const char* const*)arg3);
|
|
|
|
break;
|
2023-06-11 03:28:43 +03:00
|
|
|
case SYS_SLEEP:
|
|
|
|
ret = sys_sleep((unsigned int)arg1);
|
|
|
|
break;
|
2023-06-04 17:57:24 +03:00
|
|
|
case SYS_WAIT:
|
|
|
|
ret = sys_wait((pid_t)arg1, (int*)arg2, (int)arg3);
|
|
|
|
break;
|
2023-06-11 00:54:04 +03:00
|
|
|
case SYS_FSTAT:
|
|
|
|
ret = sys_fstat((int)arg1, (struct stat*)arg2);
|
2023-06-05 14:36:17 +03:00
|
|
|
break;
|
2023-06-05 22:43:26 +03:00
|
|
|
case SYS_SETENVP:
|
|
|
|
ret = sys_setenvp((char**)arg1);
|
|
|
|
break;
|
2023-06-11 00:18:08 +03:00
|
|
|
case SYS_READ_DIR_ENTRIES:
|
|
|
|
ret = sys_read_dir_entries((int)arg1, (API::DirectoryEntryList*)arg2, (size_t)arg3);
|
|
|
|
break;
|
2023-06-11 22:15:35 +03:00
|
|
|
case SYS_SET_UID:
|
|
|
|
ret = sys_set_uid((uid_t)arg1);
|
|
|
|
break;
|
|
|
|
case SYS_SET_GID:
|
|
|
|
ret = sys_set_gid((gid_t)arg1);
|
|
|
|
break;
|
|
|
|
case SYS_SET_EUID:
|
|
|
|
ret = sys_set_euid((uid_t)arg1);
|
|
|
|
break;
|
|
|
|
case SYS_SET_EGID:
|
|
|
|
ret = sys_set_egid((gid_t)arg1);
|
|
|
|
break;
|
|
|
|
case SYS_SET_REUID:
|
|
|
|
ret = sys_set_reuid((uid_t)arg1, (uid_t)arg2);
|
|
|
|
break;
|
|
|
|
case SYS_SET_REGID:
|
|
|
|
ret = sys_set_regid((gid_t)arg1, (gid_t)arg2);
|
|
|
|
break;
|
2023-06-11 22:27:53 +03:00
|
|
|
case SYS_GET_UID:
|
|
|
|
ret = sys_get_uid();
|
|
|
|
break;
|
|
|
|
case SYS_GET_GID:
|
|
|
|
ret = sys_get_gid();
|
|
|
|
break;
|
|
|
|
case SYS_GET_EUID:
|
|
|
|
ret = sys_get_euid();
|
|
|
|
break;
|
|
|
|
case SYS_GET_EGID:
|
|
|
|
ret = sys_get_egid();
|
|
|
|
break;
|
2023-06-12 01:24:46 +03:00
|
|
|
case SYS_GET_PWD:
|
|
|
|
ret = sys_get_pwd((char*)arg1, (size_t)arg2);
|
|
|
|
break;
|
|
|
|
case SYS_SET_PWD:
|
|
|
|
ret = sys_set_pwd((const char*)arg1);
|
|
|
|
break;
|
2023-04-23 14:32:37 +03:00
|
|
|
default:
|
2023-06-11 00:18:48 +03:00
|
|
|
dwarnln("Unknown syscall {}", syscall);
|
|
|
|
ret = -ENOSYS;
|
|
|
|
break;
|
2023-03-13 15:32:46 +02:00
|
|
|
}
|
|
|
|
|
2023-04-21 10:40:24 +03:00
|
|
|
asm volatile("cli");
|
|
|
|
|
|
|
|
Thread::current().set_in_syscall(false);
|
|
|
|
|
2023-03-13 15:32:46 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|