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