Kernel: Add SYS_EXEC syscall

This commit is contained in:
Bananymous 2023-05-31 20:57:33 +03:00
parent 4da1d6fd27
commit ab61b49aca
4 changed files with 35 additions and 17 deletions

View File

@ -112,6 +112,14 @@ namespace Kernel
return 0; return 0;
} }
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();
}
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)
@ -171,6 +179,9 @@ namespace Kernel
case SYS_SLEEP: case SYS_SLEEP:
ret = sys_sleep((unsigned int)arg1); ret = sys_sleep((unsigned int)arg1);
break; break;
case SYS_EXEC:
ret = sys_exec((const char*)arg1, (const char* const*)arg2, (const char* const*)arg3);
break;
default: default:
Kernel::panic("Unknown syscall {}", syscall); Kernel::panic("Unknown syscall {}", syscall);
} }

View File

@ -19,6 +19,7 @@ __BEGIN_DECLS
#define SYS_SET_TERMIOS 12 #define SYS_SET_TERMIOS 12
#define SYS_FORK 13 #define SYS_FORK 13
#define SYS_SLEEP 14 #define SYS_SLEEP 14
#define SYS_EXEC 15
__END_DECLS __END_DECLS

View File

@ -2,8 +2,9 @@
#include <kernel/Syscall.h> #include <kernel/Syscall.h>
#include <errno.h> #include <errno.h>
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <unistd.h> #include <unistd.h>
@ -121,6 +122,14 @@ long syscall(long syscall, ...)
ret = Kernel::syscall(SYS_SLEEP, seconds); ret = Kernel::syscall(SYS_SLEEP, seconds);
break; break;
} }
case SYS_EXEC:
{
const char* pathname = va_arg(args, const char*);
const char* const* argv = va_arg(args, const char* const*);
const char* const* envp = va_arg(args, const char* const*);
ret = Kernel::syscall(SYS_EXEC, (uintptr_t)pathname, (uintptr_t)argv, (uintptr_t)envp);
break;
}
default: default:
puts("LibC: Unhandeled syscall"); puts("LibC: Unhandeled syscall");
ret = -ENOSYS; ret = -ENOSYS;
@ -138,6 +147,11 @@ long syscall(long syscall, ...)
return ret; return ret;
} }
int execv(const char* pathname, char* const argv[])
{
return syscall(SYS_EXEC, pathname, argv, nullptr);
}
pid_t fork(void) pid_t fork(void)
{ {
return syscall(SYS_FORK); return syscall(SYS_FORK);

View File

@ -10,25 +10,17 @@ int main()
{ {
printf("userspace\n"); printf("userspace\n");
FILE* fp = fopen("/usr/include/kernel/kprint.h", "r"); if (fork() == 0)
if (fp == NULL)
ERROR("fopen");
char* buffer = (char*)malloc(128);
fread(buffer, 1, 100, fp);
pid_t pid = fork();
if (pid == 0)
{ {
while (size_t n_read = fread(buffer, 1, 127, fp)) char* argv[3];
fwrite(buffer, 1, n_read, stdout); argv[0] = (char*)malloc(100); strcpy(argv[0], "/usr/bin/cat");
free(buffer); argv[1] = (char*)malloc(100); strcpy(argv[1], "/usr/include/kernel/kprint.h");
fclose(fp); argv[2] = NULL;
execv("/usr/bin/cat", (char**)argv);
ERROR("execl");
return 0; return 0;
} }
free(buffer); printf("parent\n");
fclose(fp);
return 0; return 0;
} }