21 const char* executable = process->
argv.
buffer[0];
22 if (executable ==
NULL)
100 return (
void*)header.
entry;
159 if (argv ==
NULL || argv[0] ==
NULL)
191 if (childThread ==
NULL)
202 LOG_INFO(
"spawn path=%s pid=%d\n", argv[0], child->
id);
229 char* argvTerminator =
NULL;
231 (
void**)&argvCopy, &argc) ==
ERR)
238 char* userSpacePtr = argvCopy[i];
239 char* kernelStringCopy;
241 char terminator =
'\0';
244 (
void**)&kernelStringCopy, &stringLen) ==
ERR)
254 argvCopy[i] = kernelStringCopy;
258 if (cwdString !=
NULL)
280 if (cwdString !=
NULL)
297 (
void**)&fdsCopy, &fdAmount) ==
ERR)
306 for (
uint64_t i = 0; i < fdAmount; i++)
374 if (newThread ==
NULL)
380 return newThread->
id;
#define MAX_PATH
Maximum length of filepaths.
#define assert(expression)
@ GDT_CS_RING3
Value to load into the CS register for user code.
@ GDT_CS_RING0
Value to load into the CS register for kernel code.
@ GDT_SS_RING3
Value to load into the SS register for user data.
@ GDT_SS_RING0
Value to load into the SS register for kernel data.
#define SYSCALL_DEFINE(num, returnType,...)
Macro to define a syscall.
#define SYS_THREAD_CREATE
void path_put(path_t *path)
Put a path.
#define PATHNAME(string)
Helper to create a pathname.
uint64_t pathname_init(pathname_t *pathname, const char *string)
Initialize a pathname.
#define PATH_EMPTY
Helper to create an empty path.
fd_t vfs_ctx_set_fd(vfs_ctx_t *ctx, fd_t fd, file_t *file)
Allocate a specific file descriptor in a VFS context.
file_t * vfs_ctx_get_file(vfs_ctx_t *ctx, fd_t fd)
Get a file from a VFS context.
uint64_t vfs_seek(file_t *file, int64_t offset, seek_origin_t origin)
Seek in a file.
file_t * vfs_open(const pathname_t *pathname, process_t *process)
Open a file.
uint64_t vfs_stat(const pathname_t *pathname, stat_t *buffer, process_t *process)
Get file information.
uint64_t vfs_read(file_t *file, void *buffer, uint64_t count)
Read from a file.
uint64_t vfs_walk(path_t *outPath, const pathname_t *pathname, walk_flags_t flags, process_t *process)
Walk a pathname to a path, starting from the current process's working directory.
#define LOG_INFO(format,...)
#define LOG_DEBUG(format,...)
uint64_t space_check_access(space_t *space, const void *addr, uint64_t length)
Checks if a virtual memory region is within the allowed address range of the space.
uint64_t vmm_protect(space_t *space, void *virtAddr, uint64_t length, pml_flags_t flags)
Changes memory protection flags for a virtual memory region in a given address space.
void * vmm_alloc(space_t *space, void *virtAddr, uint64_t length, pml_flags_t pmlFlags, vmm_alloc_flags_t allocFlags)
Allocates and maps virtual memory in a given address space.
process_t * process_new(process_t *parent, const char **argv, const path_t *cwd, priority_t priority)
Allocates and initializes a new process.
thread_t * loader_spawn(const char **argv, priority_t priority, const path_t *cwd)
Spawns a child process from an executable file.
NORETURN void loader_jump_to_user_space(thread_t *thread)
Performs the initial jump to userspace.
thread_t * loader_thread_create(process_t *parent, void *entry, void *arg)
Creates a new thread within an existing process.
void thread_free(thread_t *thread)
Frees a thread structure.
uint64_t thread_copy_from_user_terminated(thread_t *thread, const void *userArray, const void *terminator, uint8_t objectSize, uint64_t maxCount, void **outArray, uint64_t *outCount)
Safely copy a null-terminated array of objects from user space.
uint64_t thread_copy_from_user_pathname(thread_t *thread, pathname_t *pathname, const char *userPath)
Safely copy a string from user space and use it to initialize a pathname.
thread_t * thread_new(process_t *process)
Creates a new thread structure.
void sched_push_new_thread(thread_t *thread, thread_t *parent)
Pushes a newly created thread onto the scheduling queue.
process_t * sched_process(void)
Retrieves the process of the currently running thread.
thread_t * sched_thread(void)
Retrieves the currently running thread.
_NORETURN void sched_process_exit(uint64_t status)
Exits the current process.
#define DEREF_DEFER(ptr)
RAII-style cleanup for scoped references.
#define DEREF(ptr)
Decrement reference count.
#define CONFIG_MAX_ARGC
Maximum argument vector configuration.
#define CONFIG_MAX_FD
Maximum file descriptor configuration.
#define EINVAL
Invalid argument.
#define ESPAWNFAIL
Process spawn failed.
#define errno
Error number variable.
#define EACCES
Permission denied.
#define EBADF
Bad file number.
#define EISDIR
Is a directory.
#define ELF_PHDR_FLAGS_WRITE
#define ELF_IS_VALID(hdr)
Checks the validity of an ELF header.
#define ELF_PHDR_TYPE_LOAD
#define ROUND_DOWN(number, multiple)
#define SPAWN_FD_END
Spawn fds termination constant.
#define SPAWN_INHERIT_PRIORITY
#define PRIORITY_MAX_USER
#define PAGE_SIZE
Memory page size.
uint8_t priority_t
Priority type.
#define NULL
Pointer error value.
#define ERR
Integer error value.
__UINT64_TYPE__ tid_t
Thread Identifier.
__UINT64_TYPE__ pid_t
Process Identifier.
static void * loader_load_program(thread_t *thread)
static char ** loader_setup_argv(thread_t *thread)
static void loader_process_entry(void)
#define RFLAGS_INTERRUPT_ENABLE
#define RFLAGS_ALWAYS_SET
#define atomic_load(object)
__UINTPTR_TYPE__ uintptr_t
_PUBLIC void free(void *ptr)
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
_PUBLIC void * memset(void *s, int c, size_t n)
uint64_t size
!< Used to avoid allocations for empty argv
uint64_t amount
!< Size of the buffer in bytes.
Virtual address space structure.
Stucture used to duplicate fds in spawn().
uintptr_t top
The top of the stack, this address is not inclusive.
Thread of execution structure.
process_t * process
The parent process that the thread executes within.
stack_pointer_t kernelStack
The kernel stack of the thread.
stack_pointer_t userStack
The user stack of the thread.
tid_t id
The thread id, unique within a process_t.