Add shebang handling

This commit is contained in:
Mark
2020-07-07 22:55:50 +03:00
parent c60ddf21c9
commit ea55fbf3ee
3 changed files with 50 additions and 5 deletions
+7
View File
@@ -105,6 +105,13 @@ static int elf_bzero(mm_space_t space, uintptr_t vma_dst, size_t size) {
return 0;
}
int binfmt_is_elf(const char *ident, size_t len) {
if (len < 4) {
return 0;
}
return !strncmp(ident, "\x7F""ELF", 4);
}
int elf_load(struct process *proc, struct vfs_ioctx *ctx, struct ofile *fd, uintptr_t *entry) {
int res;
ssize_t bread;
+1
View File
@@ -5,3 +5,4 @@ struct process;
struct ofile;
int elf_load(struct process *proc, struct vfs_ioctx *ctx, struct ofile *fd, uintptr_t *entry);
int binfmt_is_elf(const char *guess, size_t len);
+42 -5
View File
@@ -120,6 +120,7 @@ int sys_execve(const char *path, const char **argv, const char **envp) {
_assert(thr);
struct process *proc = thr->proc;
_assert(proc);
char shebang[128];
if (proc->thread_count > 1) {
panic("XXX: execve() in multithreaded process\n");
@@ -136,6 +137,47 @@ int sys_execve(const char *path, const char **argv, const char **envp) {
return res;
}
if ((res = vfs_open(&proc->ioctx, &fd, path, O_RDONLY, 0)) != 0) {
kerror("%s: %s\n", path, kstrerror(res));
return res;
}
if ((res = vfs_read(&proc->ioctx, &fd, shebang, sizeof(shebang))) <= 0) {
kerror("%s: %s\n", path, kstrerror(res));
return res;
}
if (!binfmt_is_elf(shebang, res)) {
// Try checking for shebang line
if (shebang[0] == '#' && shebang[1] == '!') {
char *e = strchr(shebang, '\n');
if (!e) {
vfs_close(&proc->ioctx, &fd);
return -EINVAL;
}
*e = 0;
int argc;
for (argc = 0; argv[argc]; ++argc);
// For interpreter
++argc;
// Sanity check
_assert(argc <= 32);
const char *argv_new[argc + 1];
argv_new[0] = shebang + 2;
for (int i = 1; i < argc; ++i) {
argv_new[i] = argv[i - 1];
}
argv_new[argc] = NULL;
for (int i = 0; i < argc; ++i) {
kdebug("[%d]: %s\n", i, argv_new[i]);
}
return sys_execve(shebang + 2, argv_new, envp);
}
}
const char *e = strrchr(path, '/');
const char *name = e + 1;
if (!e) {
@@ -162,11 +204,6 @@ int sys_execve(const char *path, const char **argv, const char **envp) {
panic("Failed to copy argp/envp to new process\n");
}
if ((res = vfs_open(&proc->ioctx, &fd, path, O_RDONLY, 0)) != 0) {
kerror("%s: %s\n", path, kstrerror(res));
return res;
}
if (proc->space == mm_kernel) {
// Have to allocate a new PID for kernel -> userspace transition
proc->pid = process_alloc_pid(1); //thread_alloc_pid(1);