/* 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);
}


+ Recent posts