diff --git a/fish_shell/fish_commands.c b/fish_shell/fish_commands.c index 99a7c1a..e1a7a36 100644 --- a/fish_shell/fish_commands.c +++ b/fish_shell/fish_commands.c @@ -10,6 +10,7 @@ /* Necessary global variables */ char * builtinCommandsStr[] = { + (char *) "clear", (char *) "kek", (char *) "cd", (char *) "help", @@ -17,6 +18,7 @@ char * builtinCommandsStr[] = { }; builtinCommand *builtinCommands[] = { + &fishClear, &fishKek, &fishCd, &fishHelp, @@ -81,3 +83,16 @@ int fishKek(WordArray *args) { int getNbBuiltins() { return sizeof(builtinCommandsStr) / sizeof(char*); } + +void fishSignalHandler(int s) { + switch (s) { + default: + break; + } +} + +int fishClear(WordArray *args) { + if (args != NULL) freeWordArray(args); + system("clear"); + return EXIT_SUCCESS; +} diff --git a/fish_shell/fish_commands.h b/fish_shell/fish_commands.h index 3a72037..961f1b6 100644 --- a/fish_shell/fish_commands.h +++ b/fish_shell/fish_commands.h @@ -23,4 +23,8 @@ int fishExit(WordArray * args); int fishKek(WordArray *args); +int fishClear(WordArray *args); + +void fishSignalHandler(int s); + #endif //FISH_FISH_COMMANDS_H diff --git a/fish_shell/fish_core.c b/fish_shell/fish_core.c index 1fed8aa..1e9a1f7 100644 --- a/fish_shell/fish_core.c +++ b/fish_shell/fish_core.c @@ -1,25 +1,57 @@ // // Created by Antoine Bartuccio on 11/05/2017. -// Dont forget that Antoine Bartuccio is a faggot since 1784 (tm) // + #include #include #include #include #include +#include +#include #include "fish_core.h" #include "fish_globbing.h" #include "fish_types.h" +pipe_redirection * getRedirection(){ + static pipe_redirection * redirection = NULL; + static char template[] = "/tmp/fishXXXXXX"; + + if (redirection == NULL){ + redirection = (pipe_redirection*) malloc(sizeof(pipe_redirection)); + if (redirection == NULL) crash(); + redirection->file_name = strdup(template); + redirection->tmp_file = mkstemp(redirection->file_name); + redirection->to_use = 0; + redirection->read = 0; + } + + return redirection; + +} + +void freeRedirection(){ + pipe_redirection * redirection = getRedirection(); + close(redirection->tmp_file); + unlink(redirection->file_name); + remove(redirection->file_name); + free(redirection->file_name); + free(redirection); +} + + void fishLoop(Settings * settings){ char * line = NULL; WordList* splited = NULL; int status = 1; + pipe_redirection *r = getRedirection(); do { printf("%s", settings->PS1); line = fishReadLine(); + r->to_use = 0; + r->read = 0; splited = split(line, (char*) FISH_TOKENS); splited = fishExpand(splited); @@ -30,20 +62,24 @@ void fishLoop(Settings * settings){ } while(status != EXIT_SIGNAL); } -int countSeparators(char *string, char *separators) { +int countSeparators(char *string, char *regex) { + const char* error; + int error_offset; + int ovector[100]; int nb = 0; - int i = 0; - int k = 0; - while (string[i] != '\0'){ - while (separators[k] != '\0'){ - if (string[i] == separators[k]){ - nb++; - } - k++; - } - i++; - k = 0; + int string_size = (int) strlen(string); + int ovector_size = 100; + int offset = 0; + pcre *re = pcre_compile(regex, 0, &error, &error_offset, 0); + + if (!re) crash(); + + while (pcre_exec(re, 0, string, string_size, offset, 0, ovector, ovector_size) >= 0){ + offset = ovector[1]; + nb++; } + pcre_free(re); + return nb; } @@ -66,24 +102,26 @@ WordList * split(char *string, char *separator){ } char *fishReadLine() { + struct sigaction signal_handler; size_t bufferSize = FISH_BUFFER_SIZE; int position = 0; char *line = (char*) malloc(sizeof(char*) * bufferSize); int c; - if (line == NULL){ - crash(); - } + if (line == NULL) crash(); + + signal_handler.sa_handler = fishSignalHandler; + sigemptyset(&signal_handler.sa_mask); + signal_handler.sa_flags = 0; while (1){ + sigaction(SIGINT, &signal_handler, NULL); c = getchar(); switch (c){ case '\n': line[position] = '\0'; return line; - case EOF: - exit(EXIT_SUCCESS); default: line[position] = (char) c; } @@ -91,7 +129,7 @@ char *fishReadLine() { position++; if ((size_t) position > bufferSize){ - bufferSize+=bufferSize; + bufferSize += bufferSize; line = (char*) realloc(line, bufferSize); if (line == NULL){ crash(); @@ -99,7 +137,6 @@ char *fishReadLine() { } } - return NULL; } @@ -107,9 +144,17 @@ char *fishReadLine() { int fishLoad(WordArray *array) { pid_t pid; int status = 1; + pipe_redirection *redirection = getRedirection(); pid = fork(); if (pid == 0){ + if (redirection->to_use){ + if (redirection->read){ + dup2(redirection->tmp_file, STDIN_FILENO); + } else { + dup2(redirection->tmp_file, STDOUT_FILENO); + } + } /* Executes only in the child process */ if (execvp(array->words[0], array->words) == -1){ /* Error during system call */ @@ -121,7 +166,6 @@ int fishLoad(WordArray *array) { perror("fish"); } else { /* Handle parent process */ - /* Wait for the child process to finish */ do { waitpid(pid, &status, WUNTRACED); @@ -129,6 +173,7 @@ int fishLoad(WordArray *array) { if (status) fprintf(stderr, "%s\n", getInsult()); } freeWordArray(array); + return status; } @@ -136,6 +181,8 @@ int fishExecute(WordList *list) { WordList *splited = NULL; shell_operator op = NONE; WordArray *array = NULL; + pipe_redirection *redirection = NULL; + int pid; int signal = 1; splited = parseWordList(list, &op); @@ -160,6 +207,32 @@ int fishExecute(WordList *list) { signal = fishExecute(list); if (signal != EXIT_SIGNAL) signal = fishExecute(splited); break; + case PIPE: + redirection = getRedirection(); + redirection->to_use = 1; + redirection->read = 0; + fishExecute(list); + lseek(redirection->tmp_file, 0L, 0); + redirection->read = 1; + signal = fishExecute(splited); + lseek(redirection->tmp_file, 0L, 0); + ftruncate(redirection->tmp_file, 0); + redirection->to_use = 0; + break; + case BACKGROUND_PROCESS: + printf("Exécution en tache de fond\n"); + pid = fork(); + if(pid == 0){ + exit(fishExecute(list)); + } else if (pid < 0){ + perror("fish"); + } else if (splited->size > 0) signal = fishExecute(splited); + else { + freeWordList(splited); + splited = NULL; + signal = EXIT_SUCCESS; + } + break; default: array = wordListToWordArray(list); signal = loadRightCommand(array); @@ -197,12 +270,16 @@ WordList * parseWordList(WordList *list, shell_operator *an_operator) { char *op_str[] = { (char*) ";", (char*) "\\|\\|", - (char*) "&&" + (char*) "&&", + (char*) "\\|", + (char*) "&" }; shell_operator op[] = { OR, REVERSE_AND, - AND + AND, + PIPE, + BACKGROUND_PROCESS }; WordList *newList = NULL; int max = sizeof(op_str) / sizeof(char*); diff --git a/fish_shell/fish_core.h b/fish_shell/fish_core.h index e602ac8..8c07c6e 100644 --- a/fish_shell/fish_core.h +++ b/fish_shell/fish_core.h @@ -27,7 +27,7 @@ void fishLoop(Settings * settings); char * fishReadLine(); -int countSeparators(char *string, char *separators); // Tested +int countSeparators(char *string, char *regex); // Tested int fishLoad(WordArray *array); @@ -37,4 +37,12 @@ WordList *parseWordList(WordList *list, shell_operator *an_operator); int loadRightCommand(WordArray *array); +/* IN/OUT functions */ + +/* Get a global pipe_redirection structure */ +pipe_redirection * getRedirection(); + +/* Free redirection structure DO NOT TRY TO GET REDIRECTION AFTER */ +void freeRedirection(); + #endif //FISH_FISH_CORE_H diff --git a/fish_shell/fish_types.h b/fish_shell/fish_types.h index 818a9f0..90b609f 100644 --- a/fish_shell/fish_types.h +++ b/fish_shell/fish_types.h @@ -47,6 +47,12 @@ typedef struct { struct passwd* passwd; } Settings; +typedef struct { + int to_use; + int read; + int tmp_file; + char * file_name; +} pipe_redirection; typedef int (builtinCommand) (WordArray*); diff --git a/fish_shell_tests/FishCoreTests.cpp b/fish_shell_tests/FishCoreTests.cpp index b90efc3..c718621 100644 --- a/fish_shell_tests/FishCoreTests.cpp +++ b/fish_shell_tests/FishCoreTests.cpp @@ -29,5 +29,8 @@ TEST(command_split, split){ } TEST(count_tokens, countSeparators){ - ASSERT_TRUE(countSeparators((char*) "Ceci est un super \n test", (char*) FISH_TOKENS) == 6); + ASSERT_TRUE(countSeparators((char*) "Ceci est un super \n test", (char*) " ") == 5); + ASSERT_TRUE(countSeparators((char*) "patate | patate| patatine", (char*) "\\|") == 2); + ASSERT_TRUE(countSeparators((char*) "patate | patate| patatine |", (char*) "\\|") == 3); + ASSERT_TRUE(countSeparators((char*) "patate | patate|| patatine |", (char*) "\\|[^\\|]") == 2); }