diff --git a/apps/init.c b/apps/init.c index e1f9e063..4192bc06 100644 --- a/apps/init.c +++ b/apps/init.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -35,4 +36,7 @@ int main() stderr = fopen("/dev/console", "w"); fprintf(stderr, "init is running as PID %d\n", getpid()); + + char* argv[] = { "/bin/hello", "--help", NULL }; + syscall(SYS_exec, "/bin/hello", argv); } diff --git a/kernel/src/sys/exec.cpp b/kernel/src/sys/exec.cpp index fe0362fb..89596293 100644 --- a/kernel/src/sys/exec.cpp +++ b/kernel/src/sys/exec.cpp @@ -8,10 +8,37 @@ #include #include #include +#include + +static Result> copy_string_vector_from_userspace(u64 address) +{ + Vector result; + + const u64* user_vector = (const u64*)address; + + u64 item; + while (true) + { + if (!MemoryManager::copy_from_user_typed(user_vector, &item)) return err(EFAULT); + if (!item) break; + + auto string = TRY(MemoryManager::strdup_from_user(item)); + TRY(result.try_append(move(string))); + user_vector++; + } + + return result; +} Result sys_exec(Registers* regs, SyscallArgs args) { auto path = TRY(MemoryManager::strdup_from_user(args[0])); + auto argv = TRY(copy_string_vector_from_userspace(args[1])); + + kdbgln("exec: printing out argv (argc = %zu)", argv.size()); + for (const auto& arg : argv) { kdbgln("* %s", arg.chars()); } + + // FIXME: Make sure argv is not too big. auto inode = TRY(VFS::resolve_path(path.chars())); @@ -28,8 +55,8 @@ Result sys_exec(Registers* regs, SyscallArgs args) kinfoln("exec: image load ok, will now replace existing process image"); - // FIXME: Close only O_CLOEXEC file descriptors. - for (int i = 0; i < FD_MAX; i++) { current->fd_table[i] = {}; } + // FIXME: Close O_CLOEXEC file descriptors. + // for (int i = 0; i < FD_MAX; i++) { current->fd_table[i] = {}; } MMU::delete_userspace_page_directory(current->directory);