//Add your code here #include<stdio.h> #include<string.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> #include<sys/wait.h> #include<ctype.h> #define MAXCOM 1000 // max number of letters to be supported #define MAX_ARGS 100 // max number of commands to be supported char allDirectories[30][30]; // contains all paths specified by user // function for finding ampersand (parallel commands) int findParallelCmds(char* str, char** parallelStr) { int i; // to be used as parallel cmds counter for (i = 0; i < MAX_ARGS; i++) { parallelStr[i] = strsep(&str, "&"); printf("i value here: %d, cmd: %s\n", i, parallelStr[i]); if (parallelStr[i] == NULL) { break; } } if (i > 1) return i; else { return 0; // returns zero if no pipe is found. } } // function to handle built-in commands // if 0 is returned, it means that none of // the built-in commands was executed int useBuiltInCmds(int argc, char **args) { int noOfSysCmds = 3, chosenCmd = 0; char* listOfSysCmds[noOfSysCmds]; listOfSysCmds[0] = "exit"; listOfSysCmds[1] = "cd"; listOfSysCmds[2] = "path"; for (int i = 0; i < noOfSysCmds; i++) { if (strcmp(args[0], listOfSysCmds[i]) == 0) { chosenCmd = i + 1; break; } } switch (chosenCmd) { case 1: if (argc > 1) { printf("Error occurs\n"); char error_message[30] = "An error has occurred\n"; write(STDERR_FILENO, error_message, strlen(error_message)); return 1; } exit(0); case 2: if (argc == 1 || argc > 2) { char error_message[30] = "An error has occurred\n"; write(STDERR_FILENO, error_message, strlen(error_message)); return 1; } chdir(args[1]); return 1; case 3: if (argc == 1) { int numPaths = sizeof(allDirectories) / sizeof(allDirectories[0]); for (int i=0; i<numPaths; i++) { sprintf(allDirectories[i], "%d", '\0'); } } else { for (int i=0; i<argc-1; i++) { sprintf(allDirectories[i], "%s", args[i+1]); } } return 1; default: break; } return 0; } // function for parsing parallel command words int parseSpaceParallel(char **parallelStr, int **parallelArgsCounter, char ***parallelArgs) { return 1; } // function for parsing single command words int parseSpace(char *str, int argsCounter, char **args) { int i; for (i = 0; i < MAX_ARGS; i++) { args[i] = strsep(&str, " "); if (args[i] == NULL) break; if (strlen(args[i]) == 0 || strcmp(args[i], "\t") == 0) i--; } argsCounter = i; printf("Current counter: %d\n", argsCounter); if (useBuiltInCmds(argsCounter, args)) { // executed with built-in cmds return 1; } else { return 0; // to be executed with execv } } // this function executes when the user does not put // any argument after ./wish, meaning they use stdin void takeStdInput(char* str, int argsCounter, char **args, int **parallelArgsCounter, char ***parallelArgs) { while(1) { // print shell prompt to terminal printf("wish> "); char *line = NULL; // buffer to store each line read size_t len = 0; // length of the line read ssize_t read; // number of characters read by getline // take input line by line while ((read = getline(&line, &len, stdin)) != -1) { // remove newline character from command string if (line[strlen(line) - 1] == '\n') { line[strlen(line) - 1] = '\0'; } // copy to pointer str strcpy(str, line); // Free the line buffer free(line); // Reset the line pointer and size for the next line line = NULL; len = 0; break; } // check for parallel cmds char *parallelStr[MAX_ARGS]; int parallelCmdsNum = findParallelCmds(str, parallelStr); if (parallelCmdsNum) { printf("%d\n", parallelCmdsNum); // return a number greater than 0 //parseSpaceParallel(parallelStr, parallelArgsCounter, parallelArgs); printf("Parse parallel completed: %d\n", parseSpaceParallel(parallelStr, parallelArgsCounter, parallelArgs)); // for (int j=0;j<parallelCmds;j++) { // printf("%s\n", parallelStr[j]); // } //exit(0); } else { // no parallel cmds found printf("No parallel cmds found\n"); parseSpace(str, argsCounter, args); exit(0); } // if (parseSpace(str, argsCounter, args)) { // // // } else { // // // } } } // function to execute given batch file void takeBatchInput(char *inputFile) { FILE * fp = fopen(inputFile, "r"); if (fp == NULL) { char error_message[30] = "An error has occurred\n"; write(STDERR_FILENO, error_message, strlen(error_message)); } } int main(int argc, char *argv[]) { char str[MAXCOM]; // ptr to store command line char *args[MAX_ARGS]; // ptr to a list of arguments int argsCounter = 0; // number of arguments, including the cmd arg char **parallelArgs[MAX_ARGS]; int *parallelArgsCounter[MAX_ARGS]; //sprintf(allDirectories[0], "%s", "/bin"); // If given more than one command-line argument -> error if (argc > 2) { char error_message[30] = "An error has occurred\n"; write(STDERR_FILENO, error_message, strlen(error_message)); } // If given one argument -> prompt input else if (argc == 1) { takeStdInput(str, argsCounter, args, parallelArgsCounter, parallelArgs); } // If given a batch file -> execute commands in file else { takeBatchInput(argv[1]); } return 0; }