Skip to content
Snippets Groups Projects
Commit 6bb13964 authored by ja3-saxby's avatar ja3-saxby
Browse files

Merge branch 'feature/argument-parsing' into Alex/6-Implement-populate-stack-process

parents 3a2337ea ed4402d3
No related branches found
No related tags found
1 merge request!5Alex/6 implement populate stack process
/*
* argument_parsing.h --prototypes functions required for parsing arguments from
* command line and placing these into the program stack structure.
*
* Authored by Joshua Saxby
*/
#ifndef USERPROG_ARGUMENT_PARSING_H #ifndef USERPROG_ARGUMENT_PARSING_H
#define USERPROG_ARGUMENT_PARSING_H #define USERPROG_ARGUMENT_PARSING_H
// some macros for argument length and count limits
// TODO: decide how many arguments we want --is 255 the standard number?
#define USERPROG_ARGV_COUNT 255
// TODO: clarify what a sensible value for this is
#define USERPROG_RAW_ARGV_LENGTH 255
/* /*
* Given a string containing the command invoking the program `command_line` * Given a string containing the command invoking the program `command_line`
* and a pointer to an array of C strings (pointer to `char* argv[]`), parse * and an array of C strings (pointer to `char* argv[]`), parse `command_line`
* `command_line` into individual arguments, populate `argv` with these and * into individual arguments, populate `argv` with these and return the number
* return the number of arguments that were parsed (this is the value that can * of arguments that were parsed (this is the value that can be used for `argc`).
* be used for `argc`).
*/ */
int parse_arguments(const char* command_line, char***argv); int parse_arguments(const char* command_line, char**argv);
/* /*
* Given stack pointer `esp`, argument count `argc` and arguments array `argv`, * Given stack pointer `esp`, argument count `argc` and arguments array `argv`,
......
/*
* parse_arguments.c --implements function for parsing a command-line string
* into the program arguments contained within it.
*
* Authored by Joshua Saxby
*/
#include <stddef.h>
#include <string.h>
#include "userprog/argument_parsing.h" #include "userprog/argument_parsing.h"
int parse_arguments(const char* command_line, char***argv) { int parse_arguments(const char* command_line, char**argv) {
#warning "Implement me" int argc = 0;
// the state pointer required by strtok_r() for use between calls
char* state_pointer;
// first call to strtok_r() is the only one where string to parse is passed
argv[0] = strtok_r(command_line, " ", &state_pointer);
argc++;
// now, parse token-by-token for any additional arguments
char* token = strtok_r(NULL, " ", &state_pointer);
// continue while still tokens to read and maximum arg count is not reached
while (token != NULL && argc < USERPROG_ARGV_COUNT) {
argv[argc] = token;
argc++;
token = strtok_r(NULL, " ", &state_pointer);
}
return argc;
} }
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "userprog/argument_parsing.h"
#include "userprog/gdt.h" #include "userprog/gdt.h"
#include "userprog/pagedir.h" #include "userprog/pagedir.h"
#include "userprog/tss.h" #include "userprog/tss.h"
...@@ -20,7 +21,6 @@ ...@@ -20,7 +21,6 @@
static thread_func start_process NO_RETURN; static thread_func start_process NO_RETURN;
static bool load (const char *cmdline, void (**eip) (void), void **initial_stack_pointer); static bool load (const char *cmdline, void (**eip) (void), void **initial_stack_pointer);
/* Starts a new thread running a user program loaded by parsing /* Starts a new thread running a user program loaded by parsing
COMMAND. The new thread may be scheduled (and may even exit) COMMAND. The new thread may be scheduled (and may even exit)
before process_execute() returns. Returns the new process's before process_execute() returns. Returns the new process's
...@@ -29,24 +29,22 @@ tid_t ...@@ -29,24 +29,22 @@ tid_t
process_execute (const char *command) process_execute (const char *command)
{ {
char *command_copy; char *command_copy;
tid_t tid;
/* Make a copy of COMMAND. /* Make a copy of COMMAND.
Otherwise there's a race between the caller and load(). */ Otherwise there's a race between the caller and load(). */
command_copy = palloc_get_page (0); command_copy = palloc_get_page (0);
if (command_copy == NULL) if (command_copy == NULL)
return TID_ERROR; return TID_ERROR;
strlcpy (command_copy, command, PGSIZE); strlcpy (command_copy, command, PGSIZE);
// we need to extract out the filename from the command string
char* file_name;
char* save_ptr; // this is the save pointer expected by strtok_r()
// file name is the first part of the command-line (space-delimited)
file_name = strtok_r(command, " ", &save_ptr);
tid_t tid;
/* Create a new thread to execute COMMAND. */ /* Create a new thread to execute COMMAND. */
/* tid = thread_create (file_name, PRI_DEFAULT, start_process, command_copy);
* FIXME: right now, COMMAND is assumed to be just the filename on its own
*
* If this is not the case (if the user passed a program name with arguments),
* then loading will fail.
* NOTE: remove this comment block when argument parsing is implemented.
*/
tid = thread_create (command, PRI_DEFAULT, start_process, command_copy);
if (tid == TID_ERROR) if (tid == TID_ERROR)
palloc_free_page (command_copy); palloc_free_page (command_copy);
...@@ -218,7 +216,7 @@ static bool load_segment (struct file *file, off_t ofs, uint8_t *upage, ...@@ -218,7 +216,7 @@ static bool load_segment (struct file *file, off_t ofs, uint8_t *upage,
uint32_t read_bytes, uint32_t zero_bytes, uint32_t read_bytes, uint32_t zero_bytes,
bool writable); bool writable);
/* Loads an ELF executable from FILE_NAME into the current thread. /* Loads an ELF executable from COMMAND into the current thread.
Stores the executable's entry point into *EIP Stores the executable's entry point into *EIP
and its initial stack pointer into *initial_stack_pointer. and its initial stack pointer into *initial_stack_pointer.
Returns true if successful, false otherwise. */ Returns true if successful, false otherwise. */
...@@ -232,6 +230,14 @@ load (const char *cmdline, void (**eip) (void), void **initial_stack_pointer) ...@@ -232,6 +230,14 @@ load (const char *cmdline, void (**eip) (void), void **initial_stack_pointer)
bool success = false; bool success = false;
int i; int i;
// extract arguments (including file name)
char* argv[USERPROG_ARGV_COUNT];
// copy the command string so we have a separate copy to manipulate
char command_copy[USERPROG_RAW_ARGV_LENGTH];
strlcpy(command_copy, cmdline, USERPROG_RAW_ARGV_LENGTH);
int argc = parse_arguments(command_copy, argv);
char* file_name = argv[0]; // file name is always argument 0
/* Allocate and activate page directory. */ /* Allocate and activate page directory. */
t->pagedir = pagedir_create (); t->pagedir = pagedir_create ();
if (t->pagedir == NULL) if (t->pagedir == NULL)
...@@ -239,7 +245,7 @@ load (const char *cmdline, void (**eip) (void), void **initial_stack_pointer) ...@@ -239,7 +245,7 @@ load (const char *cmdline, void (**eip) (void), void **initial_stack_pointer)
process_activate (); process_activate ();
/* Open executable file. */ /* Open executable file. */
file = filesys_open (cmdline); file = filesys_open (file_name);
if (file == NULL) if (file == NULL)
{ {
...@@ -320,7 +326,7 @@ load (const char *cmdline, void (**eip) (void), void **initial_stack_pointer) ...@@ -320,7 +326,7 @@ load (const char *cmdline, void (**eip) (void), void **initial_stack_pointer)
} }
/* Set up stack. */ /* Set up stack. */
if (!setup_stack (initial_stack_pointer)) if (!setup_stack (initial_stack_pointer, argv, argc))
goto done; goto done;
/* Start address. */ /* Start address. */
...@@ -456,6 +462,7 @@ setup_stack (void **initial_stack_pointer, char **argv, int argc) ...@@ -456,6 +462,7 @@ setup_stack (void **initial_stack_pointer, char **argv, int argc)
success = install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true); success = install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true);
if (success) { if (success) {
*initial_stack_pointer = PHYS_BASE - 12; *initial_stack_pointer = PHYS_BASE - 12;
populate_stack(initial_stack_pointer, argc, argv);
} else } else
palloc_free_page (kpage); palloc_free_page (kpage);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment