Created
October 7, 2014 01:16
-
-
Save ggreenleaf/9c8c0bc50d656336c7be to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //Assingment 2 shell | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <unistd.h> | |
| #include <fcntl.h> | |
| #include <sys/types.h> | |
| #include <sys/stat.h> | |
| #define ERRFORK printf("ERROR: fork faild\n"); | |
| #define ERREXEC printf("ERROR: exec failed\n"); | |
| //prototypes | |
| void parsecmd(char*, char**); //parse command into array of arguments | |
| void clearargv(char**); | |
| _Bool opcmp(const char*); | |
| void parseargvs(const char**, char**, char**); | |
| void execute(char**); //run command | |
| void execpipe(char**); | |
| void execapp (char**); | |
| void execin (char**); | |
| void execout (char**); | |
| const int ARGC = 64; | |
| int main() | |
| { | |
| char line[256]; | |
| char prompt[] = "grsh$ "; | |
| char *argv[64]; //cmd line arguments | |
| //3d array of arguments | |
| //arg[1] - |> > >> null if one command | |
| //arg[2] - first command of redirect/ IO | |
| //arg[3] - seccond command | |
| /* spit out the prompt */ | |
| // /* Try getting input. If error or EOF, exit */ | |
| while( 1 ) | |
| { | |
| /* fgets leaves '\n' in input buffer. ditch it */ | |
| printf("%s",prompt); | |
| fgets(line, sizeof line, stdin); | |
| line[strlen(line)-1] = '\0'; | |
| // This is where I take the easy route. | |
| // system(line); | |
| // fork(), execvp() & co. go here in your version | |
| if (strstr(line,">>")) | |
| { | |
| parsecmd(line, argv); | |
| execapp(argv); | |
| } | |
| else if (strstr(line,">")) | |
| { | |
| parsecmd(line, argv); | |
| execout(argv); | |
| } | |
| else if (strstr(line,"<")) | |
| { | |
| parsecmd(line, argv); | |
| execin(argv); | |
| } | |
| else if (strstr(line,"|")) | |
| { | |
| parsecmd(line, argv); | |
| execpipe(argv); | |
| } | |
| else | |
| { | |
| parsecmd(line,argv); | |
| if (strcmp(argv[0],"list") == 0) | |
| argv[0] = "ls"; //change first argument to ls command | |
| else if (strcmp(argv[0],"exit") == 0 ) | |
| exit(0); | |
| execute(argv); | |
| } | |
| clearargv(argv); | |
| } | |
| return 0; | |
| } | |
| //taken from csl.mtu.edu | |
| void parsecmd(char *line, char **argv) | |
| { | |
| while (*line != '\0') /* if not the end of line ....... */ | |
| { | |
| while (*line == ' ' || *line == '\t' || *line == '\n') | |
| *line++ = '\0'; /* replace white spaces with 0 */ | |
| *argv++ = line; /* save the argument position */ | |
| while (*line != '\0' && *line != ' ' && | |
| *line != '\t' && *line != '\n') | |
| line++; /* skip the argument until ... */ | |
| } | |
| *argv = '\0'; /* mark the end of argument list */ | |
| } | |
| void clearargv(char **argv) | |
| { | |
| for (int i = 0; i < ARGC; i++) //not good | |
| { | |
| argv[i] = NULL; | |
| } | |
| } | |
| void execute(char **argv) | |
| { | |
| pid_t pid; | |
| pid = fork(); | |
| if (pid < 0 ) //fork a child process | |
| { | |
| ERRFORK | |
| exit(1); | |
| } | |
| else if (pid == 0 ) | |
| { | |
| if (execvp(*argv,argv) < 0 ) | |
| { | |
| ERREXEC | |
| exit(1); | |
| } | |
| } | |
| else | |
| { | |
| wait(NULL); | |
| } | |
| } | |
| void execpipe (char **argv) | |
| { | |
| char *cmdArgv1[10]; | |
| char *cmdArgv2[10]; | |
| parseargvs(argv,cmdArgv1,cmdArgv2); | |
| int pfd[2]; | |
| pid_t pid, pid2; | |
| pid2 = fork(); | |
| if ( pid2 == 0 ) | |
| { | |
| pipe(pfd); | |
| pid = fork(); | |
| if (pid < 0) | |
| { | |
| ERRFORK | |
| exit(1); | |
| } | |
| else if (pid == 0) | |
| { | |
| close(pfd[1]); | |
| dup2(pfd[0],0); | |
| close(pfd[0]); | |
| execvp(cmdArgv2[0],cmdArgv2); | |
| } | |
| else | |
| { | |
| close(pfd[0]); | |
| dup2(pfd[1],1); | |
| close(pfd[1]); | |
| execvp(cmdArgv1[0],cmdArgv1); | |
| } | |
| } | |
| else | |
| { | |
| wait(NULL); | |
| wait(NULL); | |
| } | |
| } | |
| // execute input file | |
| //ex less < grsh.c | |
| void execin (char **argv) | |
| { | |
| char *cmdArgv1[10]; | |
| char *cmdArgv2[10]; //input will only be 0 | |
| parseargvs(argv,cmdArgv1,cmdArgv2); | |
| int pid = fork(); | |
| if (pid < 0 ) | |
| { | |
| ERRFORK | |
| exit(1); | |
| } | |
| else if ( pid == 0) | |
| { | |
| int in; | |
| in = open(cmdArgv2[0], O_RDONLY); | |
| dup2(in,0); //replace stdin with file input | |
| close(in); | |
| if (execvp(*cmdArgv1,cmdArgv1) < 0) | |
| { | |
| ERREXEC | |
| exit(1); | |
| } | |
| } | |
| else | |
| wait(NULL); | |
| } | |
| void execout (char **argv) | |
| { | |
| char *cmdArgv1[10]; | |
| char *cmdArgv2[10]; //input will only be 0 | |
| parseargvs(argv,cmdArgv1,cmdArgv2); | |
| int pid = fork(); | |
| if (pid < 0 ) | |
| { | |
| ERRFORK | |
| exit(1); | |
| } | |
| else if ( pid == 0) | |
| { | |
| int out; | |
| out = open(cmdArgv2[0], O_WRONLY | O_TRUNC | O_CREAT, 0700); | |
| dup2(out,1); //replace stdout with output file | |
| close(out); | |
| if (execvp(*cmdArgv1,cmdArgv1) < 0) | |
| { | |
| ERREXEC | |
| exit(1); | |
| } | |
| } | |
| else | |
| wait(NULL); | |
| } | |
| void execapp (char **argv) | |
| { | |
| char *cmdArgv1[10]; | |
| char *cmdArgv2[10]; //input will only be 0 | |
| parseargvs(argv,cmdArgv1,cmdArgv2); | |
| int pid = fork(); | |
| if (pid < 0 ) | |
| { | |
| ERRFORK | |
| exit(1); | |
| } | |
| else if ( pid == 0) | |
| { | |
| int out; | |
| out = open(cmdArgv2[0], O_WRONLY | O_APPEND | O_CREAT, 0700); | |
| dup2(out,1); //replace stdout with output file | |
| close(out); | |
| if (execvp(*cmdArgv1,cmdArgv1) < 0) | |
| { | |
| ERREXEC | |
| exit(1); | |
| } | |
| } | |
| else | |
| wait(NULL); | |
| } | |
| // compares string and returns true if | > >> < else false | |
| _Bool opcmp(const char* str) | |
| { | |
| return (strcmp(">>",str) == 0 || strcmp(">",str) == 0 | |
| || strcmp("<",str) == 0 || strcmp("|", str) == 0 ); | |
| } | |
| //copies arguments from argv into cmdArgv1 | |
| // if | < > >> is in argument move next args to cmdArgv2 | |
| void parseargvs(const char **argv, char **cmdArgv1, char **cmdArgv2) | |
| { | |
| int i = 0; | |
| while (!opcmp(argv[i])) | |
| { | |
| cmdArgv1[i] = argv[i]; | |
| i++; | |
| } | |
| cmdArgv1[i] = '\0'; | |
| i++; | |
| int j = 0; | |
| while (argv[i] != '\0') | |
| { | |
| cmdArgv2[j] = argv[i]; | |
| i++; j++; | |
| } | |
| } | |
| //Assingment 2 shell |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment