Big commit: Setup outline for piping, piping has errors still, cleaned code
This commit is contained in:
		
							parent
							
								
									4b3f4c1433
								
							
						
					
					
						commit
						b33abaf517
					
				| @ -1,11 +1,14 @@ | |||||||
| #ifndef COMMON_H | #ifndef COMMON_H | ||||||
| #define COMMON_H | #define COMMON_H | ||||||
| 
 | 
 | ||||||
|  | const char* GetHomeDir(void); | ||||||
|  | 
 | ||||||
| typedef struct CommandStruct { | typedef struct CommandStruct { | ||||||
|     char* argv[100]; // Max 100 commands
 |     char* argv[100]; // Max 100 commands
 | ||||||
|     int argc; |     int argc; | ||||||
| } CommandStruct; | } CommandStruct; | ||||||
| 
 | 
 | ||||||
|  | void CopyCommandStruct(CommandStruct* oldCommand, CommandStruct* newCommand, int start, int end); | ||||||
| void ResetCommandStruct(CommandStruct* command); | void ResetCommandStruct(CommandStruct* command); | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
| @ -3,16 +3,16 @@ | |||||||
| 
 | 
 | ||||||
| #include "Common.h" | #include "Common.h" | ||||||
| 
 | 
 | ||||||
| const char* GetHomeDir(void); |  | ||||||
| void CheckRedirection(CommandStruct* command); | void CheckRedirection(CommandStruct* command); | ||||||
|  | int CheckSymbol(CommandStruct* command, char symbol, int start); | ||||||
| int IntegratedCheck(CommandStruct* command); | int IntegratedCheck(CommandStruct* command); | ||||||
| void GetInput(char* inputString); | void GetInput(char* inputString); | ||||||
| void append(char *input, char *file); | void append(char *input, char *file); | ||||||
| void input(char *command); | void input(char *command); | ||||||
| void ExecPipe(); | int ExecPipe(CommandStruct* commandParent, CommandStruct* commandChild, int* pipefd); | ||||||
| void output(char *command); | void output(char *command); | ||||||
| void SplitInput(char* inputString, CommandStruct* command); | void SplitInput(char* inputString, CommandStruct* command); | ||||||
| void ParseInput(char* inputString, CommandStruct* command, char *symbol); | void ParseInput(char* inputString, CommandStruct* command, char* symbol); | ||||||
| void ReadPishrc(CommandStruct* command, char* inputString); | void RunChild(CommandStruct* commandChild, int* pipefd); | ||||||
| void ioRedirection(CommandStruct* command); | void ioRedirection(CommandStruct* command); | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -4,5 +4,6 @@ | |||||||
| #include "Common.h" | #include "Common.h" | ||||||
| 
 | 
 | ||||||
| void Pish(void); | void Pish(void); | ||||||
|  | void ReadPishrc(CommandStruct* commandParent, CommandStruct *commandChild, char* inputString); | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  | |||||||
							
								
								
									
										21
									
								
								src/Common.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								src/Common.c
									
									
									
									
									
								
							| @ -1,7 +1,28 @@ | |||||||
| #include "Common.h" | #include "Common.h" | ||||||
|  | #include <pwd.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <sys/types.h> | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | // Gets home directory location of user
 | ||||||
|  | const char* GetHomeDir(void) | ||||||
|  | { | ||||||
|  | 	char *homeDir = (getpwuid(getuid()))->pw_dir; | ||||||
|  | 	return homeDir; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Copies a range of an old command object to new command object
 | ||||||
|  | void CopyCommandStruct(CommandStruct* oldCommand, CommandStruct* newCommand, int start, int end) | ||||||
|  | { | ||||||
|  |     newCommand->argc = end - start; | ||||||
|  |     for (int i = 0; i < newCommand->argc; i++) | ||||||
|  |         newCommand->argv[i] = oldCommand->argv[i + start]; | ||||||
|  |     return; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Resets entire command object
 | ||||||
| void ResetCommandStruct(CommandStruct* command) | void ResetCommandStruct(CommandStruct* command) | ||||||
| { | { | ||||||
|     for (int i = 0; i < command->argc; i++) |     for (int i = 0; i < command->argc; i++) | ||||||
|  | |||||||
							
								
								
									
										103
									
								
								src/Integrated.c
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								src/Integrated.c
									
									
									
									
									
								
							| @ -1,22 +1,13 @@ | |||||||
| #include <assert.h> | #include <assert.h> | ||||||
| #include <fcntl.h> | #include <fcntl.h> | ||||||
| #include <pwd.h> |  | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <sys/stat.h> | #include <sys/stat.h> | ||||||
| #include <sys/types.h> |  | ||||||
| #include <sys/wait.h> | #include <sys/wait.h> | ||||||
| #include "Integrated.h" | #include "Integrated.h" | ||||||
| 
 | 
 | ||||||
| // Gets home directory location of user
 |  | ||||||
| const char *GetHomeDir(void) |  | ||||||
| { |  | ||||||
| 	char *homeDir = (getpwuid(getuid()))->pw_dir; |  | ||||||
| 	return homeDir; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Checks for commands that are built into Pish
 | // Checks for commands that are built into Pish
 | ||||||
| int IntegratedCheck(CommandStruct *command) | int IntegratedCheck(CommandStruct *command) | ||||||
| { | { | ||||||
| @ -66,35 +57,23 @@ void ParseInput(char *inputString, CommandStruct *command, char *symbol) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Reads ~/.pishrc and runs each command in the file
 | // Run child process
 | ||||||
| void ReadPishrc(CommandStruct *command, char *inputString) | void RunChild(CommandStruct* commandChild, int* pipefd) | ||||||
| { | { | ||||||
| 	char buffer[1]; | 	close(pipefd[0]); | ||||||
| 	int forkID; | 	dup2(pipefd[1], 1); | ||||||
| 	int *argc = &(command->argc); | 	close(pipefd[1]); | ||||||
| 	char* pishLocation = GetHomeDir(); | 	// This is the child process
 | ||||||
| 	strcat(pishLocation, "/.pishrc"); | 	// Setup the child's process environment here
 | ||||||
| 	int fd = open(pishLocation, O_RDONLY | O_CREAT); | 	// E.g., where is standard I/O, how to handle signals?
 | ||||||
| 	assert(fd > -1); | 	// execve() is recommended, execvpe() may be better
 | ||||||
| 	while (read(fd, buffer, 1) > 0) | 	execvp(commandChild->argv[0], commandChild->argv); | ||||||
| 	{ | 	// exec does not return if it succeeds
 | ||||||
| 		if (buffer[0] == '\n') | 	printf("ERROR: Could not execute %s\n", commandChild->argv[0]); | ||||||
| 		{ | 	exit(1); | ||||||
| 		  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); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| // Splits a string separated by spaces into an array of strings
 | // Splits a string separated by spaces into an array of strings
 | ||||||
| void SplitInput(char *inputString, CommandStruct *command) | void SplitInput(char *inputString, CommandStruct *command) | ||||||
| { | { | ||||||
| @ -114,6 +93,18 @@ void SplitInput(char *inputString, CommandStruct *command) | |||||||
| 	(*argc)--; | 	(*argc)--; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Splits a command array into left and right
 | ||||||
|  | // void SplitPipe(CommandStruct* commandLeft, CommandStruct* commandRight);
 | ||||||
|  | 
 | ||||||
|  | int CheckSymbol(CommandStruct* command, char symbol, int start) | ||||||
|  | { | ||||||
|  | 	for (int i = start; i < command->argc; i++) | ||||||
|  | 		if (command->argv[i][0] == symbol) | ||||||
|  | 			return i; | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| // Checking redirection
 | // Checking redirection
 | ||||||
| // TODO: Work on one symbol at a time
 | // TODO: Work on one symbol at a time
 | ||||||
| // 		 inputString may not be useful here, only *command
 | // 		 inputString may not be useful here, only *command
 | ||||||
| @ -188,17 +179,45 @@ void input(char *command) | |||||||
| 	dup2(newfd,0); | 	dup2(newfd,0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ExecPipe() | int ExecPipe(CommandStruct* commandParent, CommandStruct* commandChild, int* pipefd) | ||||||
| { | { | ||||||
|   //	;
 | 	char buffer[1024]; | ||||||
|  | 	int forkPID; | ||||||
|  | 	int pipeLocation = 0; | ||||||
|  | 	int startArgc = 0; | ||||||
|  | 	int endArgc = commandParent->argc; | ||||||
|  | 	while (pipeLocation >= 0) | ||||||
|  | 	{ | ||||||
|  | 		if (pipeLocation > 0) | ||||||
|  | 			startArgc = pipeLocation + 1; | ||||||
|  | 		pipeLocation = CheckSymbol(commandParent, '|', startArgc); | ||||||
|  | 		if (pipeLocation >= 0) | ||||||
|  | 			endArgc = pipeLocation - 1; | ||||||
|  | 		if (pipeLocation < 0) | ||||||
|  | 			endArgc = commandParent->argc; | ||||||
|  | 		CopyCommandStruct(commandParent, commandChild, startArgc, endArgc); | ||||||
|  | 		pipe(pipefd); | ||||||
|  | 		forkPID = fork(); | ||||||
|  | 		if (forkPID == 0) | ||||||
|  | 			return forkPID; | ||||||
|  | 		if (forkPID != 0) | ||||||
|  | 			wait(&forkPID); | ||||||
|  | 		close(pipefd[1]); | ||||||
|  | 		while (read(pipefd[0], buffer, sizeof(buffer)) != 0) | ||||||
|  | 			printf("%s", buffer); | ||||||
|  |         ResetCommandStruct(commandChild); // Clean command
 | ||||||
|  | 	} | ||||||
|  | 	return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void append(char *input, char *file) | void append(char* input, char* fileName) | ||||||
| { | { | ||||||
| 	FILE *fp; | 	char buffer[4]; | ||||||
| 	fp = fopen(file, "a+"); | 	int fd = open(fileName, O_APPEND | O_CREAT); | ||||||
| 	fputs(input, fp); | 
 | ||||||
| 	fclose(fp); | 	// fp = fopen(file, "a+");
 | ||||||
|  | 	// fputs(input, fp);
 | ||||||
|  | 	// fclose(fp);
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // check command standard input
 | // check command standard input
 | ||||||
|  | |||||||
							
								
								
									
										72
									
								
								src/Pish.c
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								src/Pish.c
									
									
									
									
									
								
							| @ -1,46 +1,80 @@ | |||||||
| #include <assert.h> | #include <assert.h> | ||||||
|  | #include <fcntl.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <sys/wait.h> | #include <sys/wait.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include "Common.h" | ||||||
| #include "Integrated.h" | #include "Integrated.h" | ||||||
| #include "Pish.h" | #include "Pish.h" | ||||||
| 
 | 
 | ||||||
|  | // Example command: ps aux | grep 'Z'
 | ||||||
|  | // Pipe left: [ps aux]
 | ||||||
|  | //      argv: [ps, aux]
 | ||||||
|  | // Pipe right: [grep 'Z']
 | ||||||
|  | //      argv: [grep, 'Z']
 | ||||||
|  | 
 | ||||||
|  | // check for first pipe, split into before and after pipe,
 | ||||||
|  | //      connect left and right execs
 | ||||||
|  | 
 | ||||||
| // Main function for Pish program
 | // Main function for Pish program
 | ||||||
| void Pish(void) | void Pish(void) | ||||||
| { | { | ||||||
|     CommandStruct commandObject = {"", 0}; |     CommandStruct commandParentObject = {"", 0}; | ||||||
|     CommandStruct* command = &commandObject; |     CommandStruct commandChildObject = {"", 0}; | ||||||
|  |     CommandStruct* commandParent = &commandParentObject; | ||||||
|  |     CommandStruct* commandChild = &commandChildObject; | ||||||
|     char inputString[1000]; // Max 1000 characters
 |     char inputString[1000]; // Max 1000 characters
 | ||||||
|     int forkPID; |     int forkPID; | ||||||
|     ReadPishrc(command, inputString); |     ReadPishrc(commandParent, commandChild, inputString); | ||||||
|     while (1) |     while (1) | ||||||
|     { |     { | ||||||
|         ResetCommandStruct(command); // Clean command
 |         int pipefd[2]; | ||||||
|  |         ResetCommandStruct(commandParent); // Clean command
 | ||||||
|         strcpy(inputString, "");    // Clean inputString
 |         strcpy(inputString, "");    // Clean inputString
 | ||||||
|         GetInput(inputString); |         GetInput(inputString); | ||||||
|         SplitInput(inputString, command); |         SplitInput(inputString, commandParent); | ||||||
|         if (IntegratedCheck(command)) |         if (IntegratedCheck(commandParent)) | ||||||
|             continue; |             continue; | ||||||
|  |         forkPID = ExecPipe(commandParent, commandChild, pipefd); | ||||||
|         // CheckRedirection(inputString, command);
 |         // CheckRedirection(inputString, command);
 | ||||||
|         CheckRedirection(command); |         // CheckRedirection(command);
 | ||||||
|         // ioRedirection(command);
 |         // ioRedirection(command);
 | ||||||
|         forkPID = fork(); |  | ||||||
|         // Child
 |         // Child
 | ||||||
|         if (forkPID == 0) |         if (forkPID == 0) | ||||||
|         { |             RunChild(commandChild, pipefd); | ||||||
|             // This is the child process
 |  | ||||||
|             // Setup the child's process environment here
 |  | ||||||
|             // E.g., where is standard I/O, how to handle signals?
 |  | ||||||
|             // 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
 |         // Parent
 | ||||||
|         // This is the parent process; Wait for the child to finish
 |         // This is the parent process; Wait for the child to finish
 | ||||||
|         wait(&forkPID); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // Reads ~/.pishrc and runs each command in the file
 | ||||||
|  | void ReadPishrc(CommandStruct *commandParent, CommandStruct *commandChild, char *inputString) | ||||||
|  | { | ||||||
|  | 	char buffer[1]; | ||||||
|  | 	int pipefd[2]; | ||||||
|  | 	int forkPID; | ||||||
|  | 	int *argc = &(commandParent->argc); | ||||||
|  | 	char* pishLocation = GetHomeDir(); | ||||||
|  | 	strcat(pishLocation, "/.pishrc"); | ||||||
|  | 	int fd = open(pishLocation, O_RDONLY | O_CREAT); | ||||||
|  | 	assert(fd > -1); | ||||||
|  | 	while (read(fd, buffer, 1) > 0) | ||||||
|  | 	{ | ||||||
|  | 		if (buffer[0] == '\n') | ||||||
|  | 		{ | ||||||
|  | 		  	SplitInput(inputString, commandParent); | ||||||
|  | 			if (IntegratedCheck(commandParent)) | ||||||
|  | 				continue; | ||||||
|  | 			forkPID = ExecPipe(commandParent, commandChild, pipefd); | ||||||
|  | 			if (forkPID == 0) | ||||||
|  | 				RunChild(commandChild, pipefd); | ||||||
|  | 			strcpy(inputString, ""); | ||||||
|  | 			ResetCommandStruct(commandParent); | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 		strcat(inputString, buffer); | ||||||
|  | 	} | ||||||
|  | 	assert(close(fd) >= 0); | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user