#include <lunaix/spike.h>
#include <lunaix/status.h>
#include <lunaix/syscall.h>
+#include <lunaix/syscall_utils.h>
#include <klibc/string.h>
size_t
exec_str_size(const char** str_arr, size_t* length)
{
+ if (!str_arr) {
+ *length = 0;
+ return 0;
+ }
+
const char* chr = *str_arr;
size_t sz = 0, len = 0;
sz += strlen(chr);
len++;
- chr = *(str_arr + sz);
+ chr = *(str_arr++);
}
*length = len;
- return sz + 1;
+ return sz + sizeof(char*);
}
void
struct mmap_param map_param = { .pvms = pvms,
.vms_mnt = param->vms_mnt,
- .flags = MAP_ANON | MAP_PRIVATE | MAP_FIXED,
+ .flags = MAP_ANON | MAP_PRIVATE,
.type = REGION_TYPE_HEAP,
.proct = PROT_READ | PROT_WRITE,
- .mlen = DEFAULT_HEAP_PAGES * PG_SIZE };
+ .mlen = PG_SIZE };
int status = 0;
struct mm_region* heap;
if ((status = mem_map(NULL, &heap, param->info.end, NULL, &map_param))) {
heap->region_copied = __heap_copied;
mm_index((void**)&pvms->heap, heap);
+
+ return status;
}
int
-exec_loadto(struct ld_param* param,
- struct v_file* executable,
- const char** argv,
- const char** envp)
+exec_load(struct ld_param* param,
+ struct v_file* executable,
+ const char** argv,
+ const char** envp)
{
int errno = 0;
.mlen = MAX_VAR_PAGES * PG_SIZE };
void* mapped;
- isr_param* intr_ctx = ¶m->proc->intr_ctx;
if ((errno = __exec_remap_heap(param, pvms))) {
goto done;
// make some handy infos available to user space
ptr_t arg_start = mapped + sizeof(struct usr_exec_param);
- memcpy(arg_start, (void*)argv, sz_argv);
- memcpy(arg_start + sz_argv, (void*)envp, sz_envp);
-
- struct usr_exec_param* param = mapped;
- *param = (struct usr_exec_param){ .argc = argv_len,
- .argv = arg_start,
- .envc = envp_len,
- .envp = arg_start + sz_argv,
- .info = param->info };
+ if (argv)
+ memcpy(arg_start, (void*)argv, sz_argv);
+ if (envp)
+ memcpy(arg_start + sz_argv, (void*)envp, sz_envp);
+
ptr_t* ustack = (ptr_t*)USTACK_TOP;
+ struct usr_exec_param* exec_param = (struct usr_exec_param*)mapped;
+
ustack[-1] = (ptr_t)mapped;
- intr_ctx->esp = &ustack[-1];
+ param->info.stack_top = &ustack[-1];
+
+ *exec_param = (struct usr_exec_param){ .argc = argv_len,
+ .argv = arg_start,
+ .envc = envp_len,
+ .envp = arg_start + sz_argv,
+ .info = param->info };
} else {
// TODO need to find a way to inject argv and envp remotely
+ // this is for the support of kernel level implementation of
+ // posix_spawn
fail("not implemented");
}
- intr_ctx->eip = param->info.ehdr_out.e_entry;
- // we will jump to new entry point (_u_start) upon syscall's
- // return so execve 'will not return' from the perspective of it's invoker
-
+ param->info.entry = param->info.ehdr_out.e_entry;
done:
return errno;
}
-__DEFINE_LXSYSCALL3(int,
- execve,
- const char*,
- filename,
- const char*,
- argv[],
- const char*,
- envp[])
+int
+exec_load_byname(struct ld_param* param,
+ const char* filename,
+ const char** argv,
+ const char** envp)
{
int errno = 0;
struct v_dnode* dnode;
goto done;
}
+ if ((errno = exec_load(param, file, argv, envp))) {
+ vfs_pclose(file, __current->pid);
+ }
+
+done:
+ return errno;
+}
+
+__DEFINE_LXSYSCALL3(int,
+ execve,
+ const char*,
+ filename,
+ const char*,
+ argv[],
+ const char*,
+ envp[])
+{
+ int errno = 0;
struct ld_param ldparam;
ld_create_param(&ldparam, __current, VMS_SELF);
- if ((errno = exec_loadto(&ldparam, file, argv, envp))) {
- vfs_pclose(file, __current->pid);
-
+ if ((errno = exec_load_byname(&ldparam, filename, argv, envp))) {
if ((ldparam.status & LD_STAT_FKUP)) {
// we fucked up our address space.
terminate_proc(11451);
schedule();
fail("should not reach");
}
+ goto done;
}
+ volatile struct exec_param* execp = __current->intr_ctx.execp;
+ execp->esp = ldparam.info.stack_top;
+ execp->eip = ldparam.info.entry;
+
+ // we will jump to new entry point (_u_start) upon syscall's
+ // return so execve 'will not return' from the perspective of it's invoker
+
done:
- return errno;
+ return DO_STATUS(errno);
}
\ No newline at end of file