/* tokenize the 'string' with a deliminator " ",
returns how many arguments in 'string' */
int get_argument_count(const char * string)
{
char * new_string = (char *)malloc(sizeof(char)*(strlen(string)+1));
strlcpy(new_string, string, strlen(string)+1);
char *token, *save_ptr;
int i=0;
for(token=strtok_r(new_string, " ", &save_ptr); token;
token=strtok_r(NULL, " ", &save_ptr))
{
i++;
}
free(new_string);
return i;
}
/* tokenize the 'parse' with a deliminator " ",
each arguments will be saved into the 'esp'. */
void argument_stack(char ** parse, int count, void ** esp)
{
/* parse = sentence including 'process and arguments'
count = argc(argument counts) through 'GetArgumentCount' func.
esp = &if_.esp */
char * command_line = *parse; // like 'echo x y z'
char * fn_copy;
fn_copy = palloc_get_page(PAL_USER);
if(fn_copy == NULL)
thread_exit();
strlcpy(fn_copy, command_line, PGSIZE);
char * token, * save_ptr;
int i=0;
int * variable_index = (int *)malloc(sizeof(int)*count);
for(token = strtok_r(fn_copy, " ", &save_ptr); token;
token = strtok_r(NULL, " ", &save_ptr))
{
printf("'%s'\n", token);
variable_index[i++] = token - fn_copy;
}
int size = strlen((char*)(*parse));
*esp -= size + 1;
int command_position = (int)*esp; // stack pointer position for command line
for(i=0; i<=size; i++)
{
*(char*)(*esp) = fn_copy[i];
*esp += 1;
}
*esp = (int)command_position;
*esp -= ((int)(*esp)%4<0? (int)(*esp)%4+4 : (int)(*esp)%4);
*esp -= 4;
*(int*)(*esp) = 0;
// argv[1,2,3,...]: arguments
for(i=count-1; i>=0; i--)
{
*esp -= 4;
*(void**)(*esp) = command_position + variable_index[i];
}
// argv[0]: process_name
*esp -= 4;
*(char **)(*esp) = (*esp + 4);
// argc: argument count
*esp -= 4;
*(int *)(*esp) = count;
// return address - fake (0)
*esp -= 4;
*(int*)(*esp) = 0;
free(variable_index);
}