now, the system call "execve" sets also the environment

This commit is contained in:
Stefan Lankes 2011-03-10 09:10:12 +01:00
parent 472b13b527
commit 604670c981
5 changed files with 62 additions and 18 deletions

View file

@ -377,25 +377,43 @@ static int load_task(load_args_t* largs)
}
// push strings on the stack
offset = DEFAULT_STACK_SIZE-MAX_ARGS-8;
offset = DEFAULT_STACK_SIZE-8;
memset((void*) (stack+offset), 0, 4);
offset -= MAX_ARGS;
memcpy((void*) (stack+offset), largs->buffer, MAX_ARGS);
idx = offset;
// push argv on the stack
offset -= largs->argc * sizeof(char*);
i = 0;
while(i<largs->argc) {
for(i=0; i<largs->argc; i++) {
((char**) (stack+offset))[i] = (char*) (stack+idx);
i++;
while((i<largs->argc) && ((char*) stack)[idx] != '\0')
while(((char*) stack)[idx] != '\0')
idx++;
idx++;
}
// push env on the stack
offset -= (largs->envc+1) * sizeof(char*);
for(i=0; i<largs->envc; i++) {
((char**) (stack+offset))[i] = (char*) (stack+idx);
while(((char*) stack)[idx] != '\0')
idx++;
idx++;
}
((char**) (stack+offset))[largs->envc] = NULL;
// push pointer to env
offset -= sizeof(char**);
if (!(largs->envc))
*((char***) (stack+offset)) = NULL;
else
*((char***) (stack+offset)) = (char**) (stack + offset + sizeof(char**));
// push pointer to argv
offset -= sizeof(char**);
*((char***) (stack+offset)) = (char**) (stack + offset + sizeof(char**));
*((char***) (stack+offset)) = (char**) (stack + offset + 2*sizeof(char**) + (largs->envc+1) * sizeof(char*));
// push argc on the stack
offset -= sizeof(int);
@ -466,12 +484,13 @@ int sys_execve(const char* fname, char** argv, char** env)
load_args_t* load_args = NULL;
char *dest, *src;
int ret, argc = 0;
int envc = 0;
node = findnode_fs((char*) fname);
if (!node || !(node->type == FS_FILE))
return -EINVAL;
// determine buffer size of argv
// determine total buffer size of argv and env
if (argv) {
while (argv[argc]) {
buffer_size += (strlen(argv[argc]) + 1);
@ -479,6 +498,13 @@ int sys_execve(const char* fname, char** argv, char** env)
}
}
if (env) {
while (env[envc]) {
buffer_size += (strlen(env[envc]) + 1);
envc++;
}
}
if (argc <= 0)
return -EINVAL;
if (buffer_size >= MAX_ARGS)
@ -490,12 +516,16 @@ int sys_execve(const char* fname, char** argv, char** env)
load_args->node = node;
load_args->argc = argc;
load_args->envc = 0;
load_args->envc = envc;
dest = load_args->buffer;
for (i=0; i<argc; i++) {
src = argv[i];
while ((*dest++ = *src++) != 0);
}
for (i=0; i<envc; i++) {
src = env[i];
while ((*dest++ = *src++) != 0);
}
spinlock_lock(&(per_core(current_task)->vma_lock));

View file

@ -28,10 +28,12 @@ extern int errno;
int main(int argc, char** argv)
{
int i;
char str[] = "Hello World!!!\n";
const char str[] = "Hello World!!!\n";
for(i=0; environ[i]; i++)
printf("environ[%d] = %s\n", i, environ[i]);
for(i=0; i<argc; i++)
printf("argv[%i] = %s\n", i, argv[i]);
printf("argv[%d] = %s\n", i, argv[i]);
write(1, str, strlen(str));

View file

@ -29,20 +29,20 @@ extern int errno;
int main(int argc, char** argv)
{
int i, status = 0;
int status = 0;
pid_t pid;
printf("Create child process...\n");
for(i=0; i<argc; i++)
printf("argv[%i] = %s\n", i, argv[i]);
pid = fork();
if (pid == 0) { // child
char* args[] = {"/bin/hello", "one", "two", "three", NULL};
char* newargs[] = {"/bin/hello", "one", "two", "three", NULL};
char* newenv[] = {"USER=root", "PATH=/bin:/sbin:/usr/bin", "PWD=/", "TEMP=/tmp", NULL};
printf("Hello from child process!\n");
execve("/bin/hello", args, environ);
execve("/bin/hello", newargs, newenv);
return errno;
} else {
printf("Hello from parent process! pid = %u\n", pid);
wait(&status);

View file

@ -20,6 +20,8 @@
SECTION .text
global _start
extern main
extern environ
extern __env
extern __do_global_dtors
extern __do_global_ctors
extern hardware_init_hook
@ -46,6 +48,17 @@ L2:
; call init function
call __do_global_ctors
; set default environment
mov eax, environ
mov edx, [esp+8]
cmp edx, 0
je L3
mov dword [eax], edx
jmp L4
L3:
mov dword [eax], __env
L4:
; arguments are already on the stack
; call the user's function
call main

View file

@ -18,5 +18,4 @@
*/
/* default environment */
char *__env[] = { "USER=root", "PATH=/bin:/sbin:/usr/bin", "PWD=/", (char *) 0 };
char **environ = __env;
char* __env[] = {"USER=root", "PATH=/bin:/sbin:/usr/bin", "PWD=/", (char*) 0};