summaryrefslogtreecommitdiffstats
path: root/src/userprog
diff options
context:
space:
mode:
Diffstat (limited to 'src/userprog')
-rw-r--r--src/userprog/process.c56
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);