Kernel: Add SYS_EXEC syscall
This commit is contained in:
parent
b48b239882
commit
24a190d1f7
|
@ -112,6 +112,14 @@ namespace Kernel
|
|||
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 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:
|
||||
ret = sys_sleep((unsigned int)arg1);
|
||||
break;
|
||||
case SYS_EXEC:
|
||||
ret = sys_exec((const char*)arg1, (const char* const*)arg2, (const char* const*)arg3);
|
||||
break;
|
||||
default:
|
||||
Kernel::panic("Unknown syscall {}", syscall);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ __BEGIN_DECLS
|
|||
#define SYS_SET_TERMIOS 12
|
||||
#define SYS_FORK 13
|
||||
#define SYS_SLEEP 14
|
||||
#define SYS_EXEC 15
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
#include <kernel/Syscall.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -121,6 +122,14 @@ long syscall(long syscall, ...)
|
|||
ret = Kernel::syscall(SYS_SLEEP, seconds);
|
||||
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:
|
||||
puts("LibC: Unhandeled syscall");
|
||||
ret = -ENOSYS;
|
||||
|
@ -138,6 +147,11 @@ long syscall(long syscall, ...)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int execv(const char* pathname, char* const argv[])
|
||||
{
|
||||
return syscall(SYS_EXEC, pathname, argv, nullptr);
|
||||
}
|
||||
|
||||
pid_t fork(void)
|
||||
{
|
||||
return syscall(SYS_FORK);
|
||||
|
|
|
@ -10,25 +10,17 @@ int main()
|
|||
{
|
||||
printf("userspace\n");
|
||||
|
||||
FILE* fp = fopen("/usr/include/kernel/kprint.h", "r");
|
||||
if (fp == NULL)
|
||||
ERROR("fopen");
|
||||
|
||||
char* buffer = (char*)malloc(128);
|
||||
fread(buffer, 1, 100, fp);
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == 0)
|
||||
if (fork() == 0)
|
||||
{
|
||||
while (size_t n_read = fread(buffer, 1, 127, fp))
|
||||
fwrite(buffer, 1, n_read, stdout);
|
||||
free(buffer);
|
||||
fclose(fp);
|
||||
char* argv[3];
|
||||
argv[0] = (char*)malloc(100); strcpy(argv[0], "/usr/bin/cat");
|
||||
argv[1] = (char*)malloc(100); strcpy(argv[1], "/usr/include/kernel/kprint.h");
|
||||
argv[2] = NULL;
|
||||
execv("/usr/bin/cat", (char**)argv);
|
||||
ERROR("execl");
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
fclose(fp);
|
||||
|
||||
printf("parent\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue