AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
execve.c File Reference

execve(): a process runs another program. More...

#include <core/system.h>
#include <core/string.h>
#include <core/arch.h>
#include <sys/proc.h>
#include <sys/sched.h>
#include <mm/pmap.h>
#include <sys/binfmt.h>
#include <sys/uaccess.h>
#include <mm/mm.h>
#include <aquila/fcntl.h>
#include <aquila/auxv.h>

Go to the source code of this file.

Macros

#define EXEC_ARG_MAX   (128 * 1024)
#define EXEC_SCRIPT_DEPTH   4

Functions

static void exec_strings_free (char **strs, int count)
 Frees an array of count strings that exec_strings_get() made.
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 NULL-terminated array of kernel copies, setting *count to how many there are and *ref to the array.
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.
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 is one, the script's path, then the script's own arguments but the first (argv[0]).
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 every architecture (and as Linux and the BSDs do).
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 envp (argc and envc strings, in kernel memory).
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 environment, before it first runs.
int proc_execve (struct thread *thread, const char *fn, char *const _argp[], char *const _envp[])
 Runs another program in a thread's process, for execve().

Detailed Description

execve(): a process runs another program.

The arguments and the environment are copied into the kernel first, since the process's memory is about to go. A script ("#!" on its first line) runs as its interpreter. Then the program is loaded (binfmt_load()), the close-on-exec descriptors are closed, and caught signals go back to their default action. Last, the program's initial stack is built, the same on every architecture (exec_stack_build()), and the architecture starts the thread at the program's entry point (arch_exec_start()).

Definition in file execve.c.

Macro Definition Documentation

◆ EXEC_ARG_MAX

#define EXEC_ARG_MAX   (128 * 1024)

Definition at line 28 of file execve.c.

Referenced by exec_strings_get(), and proc_execve().

◆ EXEC_SCRIPT_DEPTH

#define EXEC_SCRIPT_DEPTH   4

Definition at line 117 of file execve.c.

Referenced by proc_execve().

Function Documentation

◆ exec_script()

int exec_script ( struct proc * proc,
const char * path,
char ** interp,
char ** arg )
static

Reads the interpreter of a script, from "#!interpreter [argument]" on its first line.

Sets *interp to the interpreter and *arg to the argument (the rest of the line), or to NULL if the file isn't a script or there is no argument. Returns 0 or a negative errno.

Definition at line 125 of file execve.c.

References exec_script(), kfree(), vnode::mode, NULL, vnode::p, PROC_UIO, vfs_access(), vfs_close(), vfs_lookup(), vfs_read(), and VFS_X.

Referenced by exec_script(), and proc_execve().

◆ exec_script_args()

int exec_script_args ( char * interp,
char * arg,
const char * path,
char *** argp,
int * argc )
static

Makes the arguments of a script's interpreter: the interpreter, its argument from the script if there is one, the script's path, then the script's own arguments but the first (argv[0]).

They replace *argp and *argc. Returns 0 or -ENOMEM.

Definition at line 204 of file execve.c.

References exec_script_args(), kfree(), kmalloc(), and M_ZERO.

Referenced by exec_script_args(), and proc_execve().

◆ exec_stack_build()

uintptr_t exec_stack_build ( struct proc * proc,
int argc,
char *const argv[],
int envc,
char *const envp[] )
static

Builds a new program's initial stack, at the top of its user stack, as the System V ABI has it on every architecture (and as Linux and the BSDs do).

From the stack pointer up, one word each:

 argc
 argv[0] ... argv[argc - 1], NULL
 envp[0] ... envp[envc - 1], NULL
 the auxiliary vector: (type, value) pairs, AT_NULL last
 ... then the strings, at the top of the stack

The stack pointer is 16-byte aligned, as every ABI wants it at a program's entry. The C library's start code (crt0) finds everything from there. The process's address space must be the current one: its stack's pages are written directly, and come in as they are touched. Returns the stack pointer.

Definition at line 251 of file execve.c.

References proc::entry, exec_stack_build(), proc::gid, PAGE_SIZE, proc::uid, and USER_STACK.

Referenced by exec_stack_build(), and exec_start().

◆ exec_start()

void exec_start ( struct proc * proc,
int argc,
char *const argv[],
int envc,
char *const envp[] )
static

Starts a process's thread at its program's entry point, with its initial stack built from argv and envp (argc and envc strings, in kernel memory).

The process's address space must be the current one.

Definition at line 313 of file execve.c.

References arch_exec_start(), proc::entry, exec_stack_build(), exec_start(), queue::head, proc::threads, and qnode::value.

Referenced by exec_start(), init_execve(), and proc_execve().

◆ exec_strings_free()

void exec_strings_free ( char ** strs,
int count )
static

Frees an array of count strings that exec_strings_get() made.

Definition at line 31 of file execve.c.

References exec_strings_free(), and kfree().

Referenced by exec_strings_free(), exec_strings_get(), and proc_execve().

◆ exec_strings_get()

int exec_strings_get ( char *const u_strs[],
char * buf,
size_t * total,
int * count,
char *** ref )
static

Copies a NULL-terminated array of strings (the arguments or the environment) from user memory into a NULL-terminated array of kernel copies, setting *count to how many there are and *ref to the array.

Their size, strings and pointers, is added to *total, which may not go past EXEC_ARG_MAX. Each string comes in through buf, of EXEC_ARG_MAX bytes. Returns 0, or -EFAULT, -E2BIG or -ENOMEM.

Definition at line 50 of file execve.c.

References EXEC_ARG_MAX, exec_strings_free(), exec_strings_get(), kmalloc(), M_ZERO, and memcpy().

Referenced by exec_strings_get(), and proc_execve().

◆ init_execve()

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 environment, before it first runs.

The kernel calls it at boot, when no process runs yet.

Parameters
procinit's process, with its program loaded
argchow many arguments there are
argvthe arguments, in kernel memory
envchow many environment strings there are
envpthe environment strings, in kernel memory

Definition at line 332 of file execve.c.

References curthread, exec_start(), queue::head, init_execve(), NULL, vm_space::pmap, pmap_switch(), proc::threads, qnode::value, and proc::vm_space.

Referenced by init_execve(), and kmain().

◆ proc_execve()

int proc_execve ( struct thread * thread,
const char * fn,
char *const _argp[],
char *const _envp[] )

Runs another program in a thread's process, for execve().

On success, the thread starts the new program when it returns to user mode.

Parameters
threadthe thread calling execve()
fnthe program's path
_argpthe arguments, in user memory
_envpthe environment, in user memory
Returns
0, or a negative errno: -EFAULT, -E2BIG, -ENOMEM, -ELOOP (too many nested scripts), or the loader's. If loading fails after the old program is gone, the process is killed (SIGSEGV) instead.

Definition at line 358 of file execve.c.

References arch_sleep(), binfmt_load(), queue::count, EXEC_ARG_MAX, exec_script(), exec_script_args(), EXEC_SCRIPT_DEPTH, exec_start(), exec_strings_free(), exec_strings_get(), proc::exit, proc::fds, FDS_COUNT, fd::flags, kfree(), kmalloc(), NULL, thread::owner, proc_execve(), PROC_EXIT, proc_fd_close(), proc_fd_file(), proc_kill(), SIG_DFL, SIG_IGN, SIG_MAX, proc::sigaction, thread::spawned, vm_space::vm_entries, and proc::vm_space.

Referenced by proc_execve(), and sys_execve().