diff options
| author | Gustav Sörnäs <gustav@sornas.net> | 2021-02-23 18:09:44 +0100 |
|---|---|---|
| committer | Gustav Sörnäs <gustav@sornas.net> | 2021-02-23 18:09:44 +0100 |
| commit | d0374bd6ae92621d11866c639f2db1062e2477af (patch) | |
| tree | d2a2b136f48c34563dbcc1a00365ddc3eabc4fd7 /src | |
| parent | 358c0e8a8f9a61c3fd993b199917482afa502318 (diff) | |
| download | pintos-d0374bd6ae92621d11866c639f2db1062e2477af.tar.gz | |
implement argument parsing
Diffstat (limited to 'src')
| -rw-r--r-- | src/userprog/process.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/src/userprog/process.c b/src/userprog/process.c index 0be6e30..2b50edd 100644 --- a/src/userprog/process.c +++ b/src/userprog/process.c @@ -295,10 +295,64 @@ load (const char *file_name, void (**eip) (void), void **esp) goto done; } + /* Copy passed command to start of user stack. */ + size_t cmd_len = strlen (file_name); + char *esp_cmd = *esp; + esp_cmd -= cmd_len + 1; // +1 makes room for '\0' + for (size_t i = 0; i < cmd_len; i++) { + esp_cmd[i] = file_name[i]; + } + esp_cmd[cmd_len] = '\0'; + + unsigned argc = 0; + + /* Tokenize passed command in-place. */ + // esp_c still points to first character of passed command + char *token, *save_ptr; + for (token = strtok_r (esp_cmd, " ", &save_ptr); token != NULL; + token = strtok_r (NULL, " ", &save_ptr)) + { + argc++; + } + + file_name = esp_cmd; + + /* Alignment for entries of argv. */ + size_t psize = sizeof (char *); + size_t word_alignment = (cmd_len + psize) / psize; // next address to place pointer + + /* Write argv entries. */ + char **esp_argv_entry = *esp; + esp_argv_entry -= word_alignment + argc + 1; // +1 makes room for argv[argc] = NULL + + char **esp_argv_first = esp_argv_entry; + + // esp_cmd points to first entry so write directly + *esp_argv_entry = esp_cmd; + esp_argv_entry++; + + for (unsigned i = 0; i < argc - 1; i++) { + // find next \0 in cmd + while (*(++esp_cmd) != '\0') {} + *esp_argv_entry = esp_cmd + 1; + esp_argv_entry++; + } + + char *** esp_argv = esp_argv_first; + esp_argv--; + + *esp_argv = esp_argv_first; + + int *esp_argc = esp_argv; + esp_argc--; + *esp_argc = argc; + + *esp = esp_argc - 1; // return address + /* Uncomment the following line to print some debug information. This will be useful when you debug the program stack.*/ -/*#define STACK_DEBUG*/ +// #define STACK_DEBUG #ifdef STACK_DEBUG printf("*esp is %p\nstack contents:\n", *esp); |
