diff --git a/Makefile b/Makefile index 4993ac8..6d352fe 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ all: compile link compile: gcc $(INC) -c -o build/main.o src/main.c + gcc $(INC) -c -o build/Common.o src/Common.c gcc $(INC) -c -o build/Integrated.o src/Integrated.c gcc $(INC) -c -o build/Pish.o src/Pish.c @@ -13,17 +14,17 @@ link: exec: compile link ./bin/pish.out -debug: debugCompile debugLink +debug: clean debugCompile debugLink debugCompile: gcc $(INC) -g -c -o build/main.o src/main.c gcc $(INC) -g -c -o build/Integrated.o src/Integrated.c + gcc $(INC) -g -c -o build/Common.o src/Common.c gcc $(INC) -g -c -o build/Pish.o src/Pish.c debugLink: gcc -g -o bin/pish.out build/*.o - clean: rm build/*.o rm bin/*.out diff --git a/include/Common.h b/include/Common.h index 7b217a3..25ac07a 100755 --- a/include/Common.h +++ b/include/Common.h @@ -6,4 +6,6 @@ typedef struct CommandStruct { int argc; } CommandStruct; +void ResetCommandStruct(CommandStruct* command); + #endif \ No newline at end of file diff --git a/include/Integrated.h b/include/Integrated.h index 0826d06..fe2f4c3 100755 --- a/include/Integrated.h +++ b/include/Integrated.h @@ -3,6 +3,10 @@ #include "Common.h" -void IntegratedCheck(char* command); +const char* GetHomeDir(void); +void IntegratedCheck(CommandStruct* command); +void GetInput(char* inputString); +void ParseInput(char* inputString, CommandStruct* command); +void ReadPishrc(CommandStruct* command, char* inputString); #endif \ No newline at end of file diff --git a/include/Pish.h b/include/Pish.h index 1f230e4..9b54a1a 100644 --- a/include/Pish.h +++ b/include/Pish.h @@ -4,8 +4,5 @@ #include "Common.h" void Pish(void); -void Execute(char* command); -void GetInput(char* inputString); -void ParseInput(char* inputString, CommandStruct* command); #endif diff --git a/src/Common.c b/src/Common.c new file mode 100644 index 0000000..62393af --- /dev/null +++ b/src/Common.c @@ -0,0 +1,11 @@ +#include "Common.h" +#include +#include + +void ResetCommandStruct(CommandStruct* command) +{ + for (int i = 0; i < command->argc; i++) + command->argv[i] = ""; + command->argc = 0; + return; +} diff --git a/src/Integrated.c b/src/Integrated.c index 00103c8..d578754 100755 --- a/src/Integrated.c +++ b/src/Integrated.c @@ -1,14 +1,91 @@ +#include +#include +#include #include +#include +#include +#include +#include +#include +#include #include "Integrated.h" -// Checks for commands that are built into Pish -void IntegratedCheck(char* command) +// Gets home directory location of user +const char* GetHomeDir(void) { - if (command == "exit") + char* homeDir = (getpwuid(getuid()))->pw_dir; + strcat(homeDir, "/.pishrc"); + return homeDir; +} + + +// Checks for commands that are built into Pish +void IntegratedCheck(CommandStruct* command) +{ + if (strcmp(command->argv[0], "exit") == 0) exit(0); // If there is an argument, change to argument location // Else, change to home directory - if (command[0] == 'c' && command[1] == 'd') + if (command->argv[0][0] == 'c' && command->argv[0][1] == 'd') ; return; -} \ No newline at end of file +} + + +// Prints a prompt and then reads a command from the terminal +void GetInput(char* inputString) +{ + char c; + char* prompt = "pish%>"; + printf("%s ", prompt); + // assert(scanf("%[^\n]s", inputString) == 1); + scanf("%1000[^\n]s", inputString); + while((c = getchar()) != '\n' && c != EOF) + /* discard */ ; + return; +} + +// Splits a string separated by spaces into an array of strings +void ParseInput(char* inputString, CommandStruct* command) +{ + //Parse command + int* argc = &(command->argc); + char* token = strtok(inputString, " "); + command->argv[*argc] = token; + (*argc)++; + while (token != NULL) + { + //This only holds 1 command at a time then it overrides + //Will need modified + token = strtok(NULL, " "); + command->argv[*argc] = token; + (*argc)++; + } +} + +// Reads ~/.pishrc and runs each command in the file +void ReadPishrc(CommandStruct* command, char* inputString) +{ + char buffer[1]; + int forkID; + int* argc = &(command->argc); + int fd = open(GetHomeDir(), O_RDONLY | O_CREAT); + assert(fd > -1); + while (read(fd, buffer, 1) > 0) + { + if (buffer[0] == '\n') + { + ParseInput(inputString, command); + forkID = fork(); + if (forkID == 0) + execvp(command->argv[0], command->argv); + else + wait(&forkID); + strcpy(inputString, ""); + ResetCommandStruct(command); + continue; + } + strcat(inputString, buffer); + } + assert(close(fd) >= 0); +} diff --git a/src/Pish.c b/src/Pish.c index 76f6191..cc42bf7 100644 --- a/src/Pish.c +++ b/src/Pish.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -13,11 +14,14 @@ void Pish(void) CommandStruct* command = &commandObject; char inputString[1000]; // Max 1000 characters int forkPID; + ReadPishrc(command, inputString); while (1) { + ResetCommandStruct(command); // Clean command + strcpy(inputString, ""); // Clean inputString GetInput(inputString); ParseInput(inputString, command); - IntegratedCheck(command->argv[0]); + IntegratedCheck(command); forkPID = fork(); // Child if (forkPID == 0) @@ -25,56 +29,14 @@ void Pish(void) // This is the child process // Setup the child's process environment here // E.g., where is standard I/O, how to handle signals? - // TODO: Adjust Execute() to handle CommandStruct - Execute(inputString); + // execve() is recommended, execvpe() may be better + execvp(command->argv[0], command->argv); // exec does not return if it succeeds printf("ERROR: Could not execute %s\n", inputString); exit(1); } // Parent - else - { - // This is the parent process; Wait for the child to finish - // Removed due to potentially useless - // int pid = forkPID; - // wait(&pid); - wait(&forkPID); - } - // TODO: Remove break when while loop doesn't break program - break; + // This is the parent process; Wait for the child to finish + wait(&forkPID); } } - -// Executes a command to the system -void Execute(char* command) -{ - printf("%s\n", command); - system(command); - exit(0); -} - -// Prints a prompt and then reads a command from the terminal -void GetInput(char* inputString) -{ - char prompt = '$'; - printf("%c ", prompt); - scanf("%[^\n]", inputString); - return; -} - -void ParseInput(char* inputString, CommandStruct* command) -{ - //Parse command - int* count = &(command->argc); - char* token = strtok(inputString, " "); - command->argv[*count] = token; - (*count)++; - while (token != NULL) - { - //This only holds 1 command at a time then it overrides - //Will need modified - token = strtok(NULL, " "); - command->argv[*count] = token; - (*count)++; - } -}