Vhex-kernel/src/kernel/scheduler/syscall/sys_fexecve.c

119 lines
2.7 KiB
C

#include <kernel/process.h>
#include <kernel/scheduler.h>
#include <kernel/loader.h>
#include <kernel/util/atomic.h>
#include <kernel/devices/earlyterm.h>
#include <kernel/memory.h>
#include <string.h>
//TODO
//TODO COPY-ON-WRITE !!
//TODO
static void proc_dump_shared(struct process *child, struct process *parent)
{
for (int i = 0 ; i < PROCESS_NB_OPEN_FILE ; ++i)
{
memcpy(&child->opfile[i].file, &parent->opfile[i].file, sizeof(FILE));
child->opfile[i].status = parent->opfile[i].status;
}
}
static int generate_arguments(struct process *proc, char **argv, char **envp)
{
// Generate argc
proc->context.reg[4] = -1;
while (argv[++proc->context.reg[4]] != NULL);
// Generate process argv area
proc->context.reg[5] = (uint32_t)pm_heap_alloc(&proc->memory.heap, sizeof(char*) * proc->context.reg[4]);
if (proc->context.reg[5] == 0x00000000)
return (-1);
// Dump argv
for (uint32_t i = 0 ; i < proc->context.reg[4] ; ++i)
{
((char**)proc->context.reg[5])[i] = pm_heap_alloc(&proc->memory.heap, strlen(argv[i]));
strcpy(((char**)proc->context.reg[5])[i], argv[i]);
}
//TODO: envp
(void)envp;
return (0);
}
//TODO
//TODO RENAME ME !!!!!
//TODO Return EAGAIN if no proc can be created !!
//TODO Return ENOMEM if no memories can be allocated !!
//TODO
pid_t sys_fexecve(const char *pathname, char **argv, char **envp)
{
extern struct process *process_current;
struct process *proc;
// CHeck error
// TODO: set errno to EFAULT
if (argv == NULL)
return (-1);
// Start atomic operation
atomic_start();
// Try create new process
proc = process_create();
if (proc == NULL)
{
earlyterm_write("sys_fexecve: process_create error !\n");
DBG_WAIT;
atomic_stop();
return (-1);
}
// Dump parent process shared informations
if (process_current != NULL)
proc_dump_shared(proc, process_current);
// Try to load binary into physical memory
if (loader(proc, pathname) != 0)
{
earlyterm_write("sys_fexecve: loader error !\n");
DBG_WAIT;
process_free(proc);
atomic_stop();
return (-1);
}
// Generate arguments
if (generate_arguments(proc, argv, envp) != 0)
{
earlyterm_write("sys_fexecve: arguements error\n");
DBG_WAIT;
process_free(proc);
atomic_stop();
return (-1);
}
// Release child process
proc->sibling = process_current->child;
process_current->child = proc;
// Add new process into task queue
if (sched_task_add(proc))
{
earlyterm_write("sys_fexecve: scheduler error !\n");
DBG_WAIT;
process_free(proc);
atomic_stop();
return (-1);
}
// Debug
//earlyterm_write("New proc sched added !\n");
///earlyterm_write("New proc PID = %#x !\n", proc->pid);
//DBG_WAIT;
// Stop atomic operations
atomic_stop();
return (proc->pid);
}