23#include <aquila/fcntl.h>
24#include <aquila/auxv.h>
28#define EXEC_ARG_MAX (128 * 1024)
36 for (
int i = 0; i < count; ++i)
50static int exec_strings_get(
char *
const u_strs[],
char *buf,
size_t *total,
int *count,
char ***ref)
56 for (; u_strs; ++cnt) {
57 if (copyin(&u, &u_strs[cnt],
sizeof(u)))
67 char **strs =
kmalloc((cnt + 1) *
sizeof(
char *), &M_BUFFER,
M_ZERO);
72 for (
int i = 0; i < cnt; ++i) {
77 if (copyin(&u, &u_strs[i],
sizeof(u)) || !u) {
82 if (!room || (len = copyinstr(buf, u, room)) == -ENAMETOOLONG) {
92 *total += len + 1 +
sizeof(
char *);
99 if (!(strs[i] =
kmalloc(len + 1, &M_BUFFER, 0))) {
104 memcpy(strs[i], buf, len + 1);
117#define EXEC_SCRIPT_DEPTH 4
132 *interp = *arg =
NULL;
150 if (len < 2 || buf[0] !=
'#' || buf[1] !=
'!')
156 while (*end && *end !=
'\n')
166 while (*
p ==
' ' || *
p ==
'\t')
170 while (*
p && *
p !=
' ' && *
p !=
'\t')
179 while (*
p ==
' ' || *
p ==
'\t')
183 while (end >
p && (end[-1] ==
' ' || end[-1] ==
'\t'))
186 if (!(*interp = strdup(name)))
189 if (*
p && !(*arg = strdup(
p))) {
204static int exec_script_args(
char *interp,
char *arg,
const char *path,
char ***argp,
int *argc)
206 int count = 1 + !!arg + 1 + (*argc > 1 ? *argc - 1 : 0);
207 char **args =
kmalloc((count + 1) *
sizeof(
char *), &M_BUFFER,
M_ZERO);
208 char *script = strdup(path);
210 if (!args || !script) {
222 for (
int j = 1; j < *argc; ++j)
223 args[i++] = (*argp)[j];
264 const int nauxv =
sizeof(auxv) /
sizeof(auxv[0]);
270 for (
int i = 0; i < argc; ++i)
271 strings += strlen(argv[i]) + 1;
273 for (
int i = 0; i < envc; ++i)
274 strings += strlen(envp[i]) + 1;
280 size_t words = 1 + (argc + 1) + (envc + 1) + 2 * nauxv;
286 for (
int i = 0; i < argc; ++i) {
287 strcpy(str, argv[i]);
289 str += strlen(argv[i]) + 1;
294 for (
int i = 0; i < envc; ++i) {
295 strcpy(str, envp[i]);
297 str += strlen(envp[i]) + 1;
302 for (
int i = 0; i < nauxv; ++i) {
313static void exec_start(
struct proc *
proc,
int argc,
char *
const argv[],
int envc,
char *
const envp[])
363 int argc = 0, envc = 0;
384 for (
int depth = 0;; ++depth) {
397 err = err ? err : -ELOOP;
428 for (
int i = 0; i <=
SIG_MAX; ++i) {
void arch_exec_start(struct thread *thread, uintptr_t entry, uintptr_t sp)
Sets up a thread to start a new program when it next returns to user mode: at its entry point,...
void arch_sleep(void)
Puts the current thread to sleep.
int binfmt_load(struct proc *proc, const char *path, struct proc **ref)
Loads a program into a process, for execve().
int vfs_close(struct vnode *vnode)
Drops a reference to a vnode.
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
void kfree(void *)
Frees an object that kmalloc() gave.
void * memcpy(void *dst, const void *src, size_t n)
Copies n bytes; dst and src must not overlap.
int vfs_lookup(const char *path, struct uio *uio, struct vnode **ref)
Finds the vnode a path names.
struct pmap * pmap_switch(struct pmap *pmap)
Switches this CPU to an address space's page tables.
int proc_fd_close(struct proc *proc, int fd)
Closes a descriptor: it is free again, and its reference to the open file is dropped.
int proc_execve(struct thread *thread, const char *fn, char *const argv[], char *const env[])
Runs another program in a thread's process, for execve().
struct file * proc_fd_file(struct proc *proc, int fd)
Finds the open file a descriptor refers to.
#define PROC_EXIT(info, code)
void init_execve(struct proc *proc, int argc, char *const argv[], int envc, char *const envp[])
Sets up init, the first process, to start its program: its initial stack with its arguments and envir...
void proc_kill(struct proc *proc)
Ends a process: its threads end, its descriptors are closed, its memory is freed, its children go to ...
ssize_t vfs_read(struct vnode *vnode, off_t off, size_t size, void *buf)
Reads from a vnode into a kernel buffer.
A file descriptor: the open file it refers to (fs/file.c, shared with the descriptors that dup() and ...
struct aquila_sigaction sigaction[SIG_MAX+1]
its signal actions
struct vm_space vm_space
its address space
int exit
its exit status (PROC_EXIT())
struct fd * fds
its file descriptors (FDS_COUNT of them)
uid_t uid
its user and group IDs
struct queue threads
its threads
uintptr_t entry
its program's entry point
int spawned
whether it has run yet
struct proc * owner
its process
Who does a filesystem operation: where its paths start, and its credentials and umask.
struct pmap * pmap
its page tables (the architecture's)
struct queue vm_entries
its mappings (map entries), in address order
A file in memory (a vnode): what its inode says, and the kernel's own state.
void * p
the filesystem's own data
static int exec_script(struct proc *proc, const char *path, char **interp, char **arg)
Reads the interpreter of a script, from "#!interpreter [argument]" on its first line.
#define EXEC_SCRIPT_DEPTH
static uintptr_t exec_stack_build(struct proc *proc, int argc, char *const argv[], int envc, char *const envp[])
Builds a new program's initial stack, at the top of its user stack, as the System V ABI has it on eve...
static void exec_strings_free(char **strs, int count)
Frees an array of count strings that exec_strings_get() made.
static void exec_start(struct proc *proc, int argc, char *const argv[], int envc, char *const envp[])
Starts a process's thread at its program's entry point, with its initial stack built from argv and en...
static int exec_script_args(char *interp, char *arg, const char *path, char ***argp, int *argc)
Makes the arguments of a script's interpreter: the interpreter, its argument from the script if there...
static int exec_strings_get(char *const u_strs[], char *buf, size_t *total, int *count, char ***ref)
Copies a NULL-terminated array of strings (the arguments or the environment) from user memory into a ...
int vfs_access(struct vnode *vnode, struct uio *uio, int mode)
Checks whether a user may access a vnode in a way: the owner's permissions apply to its owner,...