From de18074b896ca6907a8a859ad1714b7d8eb8eb58 Mon Sep 17 00:00:00 2001 From: klmp200 Date: Sun, 11 Jun 2017 02:10:11 +0200 Subject: [PATCH 1/5] =?UTF-8?q?Support=20de=20l'op=C3=A9rateur=20&=20et=20?= =?UTF-8?q?support=20basique=20du=20|=20sur=20seulement=201=20niveau?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fish_shell/fish_commands.c | 15 ++++ fish_shell/fish_commands.h | 4 + fish_shell/fish_core.c | 123 +++++++++++++++++++++++------ fish_shell/fish_core.h | 10 ++- fish_shell/fish_types.h | 6 ++ fish_shell_tests/FishCoreTests.cpp | 5 +- 6 files changed, 138 insertions(+), 25 deletions(-) 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); } From c0e130cb71c6da481f0fec039a21f2508806a360 Mon Sep 17 00:00:00 2001 From: klmp200 Date: Sun, 11 Jun 2017 02:21:09 +0200 Subject: [PATCH 2/5] C++ NAZI --- fish_shell/fish_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fish_shell/fish_core.c b/fish_shell/fish_core.c index 1e9a1f7..603db35 100644 --- a/fish_shell/fish_core.c +++ b/fish_shell/fish_core.c @@ -20,7 +20,7 @@ pipe_redirection * getRedirection(){ if (redirection == NULL){ redirection = (pipe_redirection*) malloc(sizeof(pipe_redirection)); if (redirection == NULL) crash(); - redirection->file_name = strdup(template); + redirection->file_name = strdup((char*) template); redirection->tmp_file = mkstemp(redirection->file_name); redirection->to_use = 0; redirection->read = 0; From b7165df43f5d417200775f55b7457318588d5145 Mon Sep 17 00:00:00 2001 From: klmp200 Date: Sun, 11 Jun 2017 02:42:33 +0200 Subject: [PATCH 3/5] AH ! --- fish_shell/fish_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fish_shell/fish_core.c b/fish_shell/fish_core.c index 603db35..a520158 100644 --- a/fish_shell/fish_core.c +++ b/fish_shell/fish_core.c @@ -15,12 +15,11 @@ 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((char*) template); + redirection->file_name = strdup((char*) "/tmp/fishXXXXXX"); redirection->tmp_file = mkstemp(redirection->file_name); redirection->to_use = 0; redirection->read = 0; From 5e63f08650c09d82c6ec610c1def178b9e2e9226 Mon Sep 17 00:00:00 2001 From: klmp200 Date: Sun, 11 Jun 2017 17:52:05 +0200 Subject: [PATCH 4/5] Grep infinis :D --- fish_shell/fish_core.c | 69 +++++++++++++++++++++++++++++++---------- fish_shell/fish_types.h | 15 +++++++-- 2 files changed, 65 insertions(+), 19 deletions(-) diff --git a/fish_shell/fish_core.c b/fish_shell/fish_core.c index a520158..647b31e 100644 --- a/fish_shell/fish_core.c +++ b/fish_shell/fish_core.c @@ -19,10 +19,15 @@ pipe_redirection * getRedirection(){ if (redirection == NULL){ redirection = (pipe_redirection*) malloc(sizeof(pipe_redirection)); if (redirection == NULL) crash(); - redirection->file_name = strdup((char*) "/tmp/fishXXXXXX"); - redirection->tmp_file = mkstemp(redirection->file_name); + redirection->files_name[0] = strdup((char*) "/tmp/fishXXXXXX"); + redirection->files_name[1] = strdup((char*) "/tmp/fishXXXXXX"); + redirection->tmp_files[0] = mkstemp(redirection->files_name[0]); + redirection->tmp_files[1] = mkstemp(redirection->files_name[1]); redirection->to_use = 0; - redirection->read = 0; + redirection->read = WRITE; + redirection->nb = 0; + redirection->nb_max = 0; + redirection->file_use = 0; } return redirection; @@ -31,10 +36,14 @@ pipe_redirection * getRedirection(){ void freeRedirection(){ pipe_redirection * redirection = getRedirection(); - close(redirection->tmp_file); - unlink(redirection->file_name); - remove(redirection->file_name); - free(redirection->file_name); + close(redirection->tmp_files[0]); + close(redirection->tmp_files[1]); + unlink(redirection->files_name[0]); + unlink(redirection->files_name[1]); + remove(redirection->files_name[0]); + remove(redirection->files_name[1]); + free(redirection->files_name[0]); + free(redirection->files_name[1]); free(redirection); } @@ -50,7 +59,8 @@ void fishLoop(Settings * settings){ line = fishReadLine(); r->to_use = 0; - r->read = 0; + r->nb = countSeparators(line, "\\|[^\\|]"); + r->nb_max = r->nb; splited = split(line, (char*) FISH_TOKENS); splited = fishExpand(splited); @@ -148,10 +158,13 @@ int fishLoad(WordArray *array) { pid = fork(); if (pid == 0){ if (redirection->to_use){ - if (redirection->read){ - dup2(redirection->tmp_file, STDIN_FILENO); + if (redirection->read == READ){ + dup2(redirection->tmp_files[redirection->file_use], STDIN_FILENO); + } else if (redirection->read == WRITE) { + dup2(redirection->tmp_files[redirection->file_use], STDOUT_FILENO); } else { - dup2(redirection->tmp_file, STDOUT_FILENO); + dup2(redirection->tmp_files[!redirection->file_use], STDIN_FILENO); + dup2(redirection->tmp_files[redirection->file_use], STDOUT_FILENO); } } /* Executes only in the child process */ @@ -208,14 +221,38 @@ int fishExecute(WordList *list) { break; case PIPE: redirection = getRedirection(); + + if (redirection->nb == redirection->nb_max){ + redirection->read = WRITE; + redirection->file_use = 0; + } else if (redirection->nb > 0){ + redirection->read = READ_AND_WRITE; + redirection->file_use = !redirection->file_use; + } else { + redirection->read = READ; + redirection->file_use = !redirection->file_use; + } redirection->to_use = 1; - redirection->read = 0; + --redirection->nb; + + if (redirection->read == WRITE) ftruncate(redirection->tmp_files[redirection->file_use], 0); + lseek(redirection->tmp_files[0], 0L, 0); + lseek(redirection->tmp_files[1], 0L, 0); + fishExecute(list); - lseek(redirection->tmp_file, 0L, 0); - redirection->read = 1; + + redirection->read = WRITE; + if (redirection->nb > 0){ + redirection->read = READ_AND_WRITE; + } else { + redirection->read = READ; + } + if (redirection->read == WRITE) ftruncate(redirection->tmp_files[redirection->file_use], 0); + lseek(redirection->tmp_files[0], 0L, 0); + lseek(redirection->tmp_files[1], 0L, 0); + signal = fishExecute(splited); - lseek(redirection->tmp_file, 0L, 0); - ftruncate(redirection->tmp_file, 0); + redirection->to_use = 0; break; case BACKGROUND_PROCESS: diff --git a/fish_shell/fish_types.h b/fish_shell/fish_types.h index 90b609f..51f9e24 100644 --- a/fish_shell/fish_types.h +++ b/fish_shell/fish_types.h @@ -23,6 +23,12 @@ typedef enum { REVERSE_AND } shell_operator ; +typedef enum { + READ, + WRITE, + READ_AND_WRITE +} redirection_mode ; + typedef struct { char ** words; int size; @@ -49,9 +55,12 @@ typedef struct { typedef struct { int to_use; - int read; - int tmp_file; - char * file_name; + int nb; + int nb_max; + int file_use; + int tmp_files[2]; + char * files_name[2]; + redirection_mode read; } pipe_redirection; typedef int (builtinCommand) (WordArray*); From 78a4c93224d05b082b0b90a71d7175c364be0a20 Mon Sep 17 00:00:00 2001 From: klmp200 Date: Sun, 11 Jun 2017 18:43:05 +0200 Subject: [PATCH 5/5] =?UTF-8?q?Toutes=20les=20redirections=20d'entr=C3=A9e?= =?UTF-8?q?=20sortie=20comme=20un=20beau=20gosse?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fish_shell/fish_core.c | 50 ++++++++++++++++++++++++++++++++++++++--- fish_shell/fish_types.h | 7 +++++- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/fish_shell/fish_core.c b/fish_shell/fish_core.c index 647b31e..d7523a9 100644 --- a/fish_shell/fish_core.c +++ b/fish_shell/fish_core.c @@ -13,6 +13,23 @@ #include "fish_globbing.h" #include "fish_types.h" +#define REDIRECT_EXIT_FREE() signal = EXIT_FAILURE; \ + freeWordList(list);\ + freeWordList(splited); + +#define REDIRECT_STD(std, open_mode) if (splited->size == 0) {REDIRECT_EXIT_FREE()\ + } else {\ + redirect_file = fopen(splited->first->word, open_mode);\ + if (redirect_file == NULL) { REDIRECT_EXIT_FREE() } else {\ + saved_std = dup(std);\ + dup2(fileno(redirect_file), std);\ + signal = fishExecute(list);\ + dup2(saved_std, std);\ + fclose(redirect_file);\ + freeWordList(splited);\ + }\ + } + pipe_redirection * getRedirection(){ static pipe_redirection * redirection = NULL; @@ -59,7 +76,7 @@ void fishLoop(Settings * settings){ line = fishReadLine(); r->to_use = 0; - r->nb = countSeparators(line, "\\|[^\\|]"); + r->nb = countSeparators(line, (char*) "\\|[^\\|]"); r->nb_max = r->nb; splited = split(line, (char*) FISH_TOKENS); splited = fishExpand(splited); @@ -194,6 +211,8 @@ int fishExecute(WordList *list) { shell_operator op = NONE; WordArray *array = NULL; pipe_redirection *redirection = NULL; + FILE *redirect_file = NULL; + int saved_std; int pid; int signal = 1; @@ -269,6 +288,21 @@ int fishExecute(WordList *list) { signal = EXIT_SUCCESS; } break; + case REDIRECT_STDOUT_ERASE: + REDIRECT_STD(STDOUT_FILENO, "w"); + break; + case REDIRECT_STDOUT_APPEND: + REDIRECT_STD(STDOUT_FILENO, "a"); + break; + case REDIRECT_STDERR_ERASE: + REDIRECT_STD(STDERR_FILENO, "w"); + break; + case REDIRECT_STDERR_APPEND: + REDIRECT_STD(STDERR_FILENO, "a"); + break; + case REDIRECT_STDIN: + REDIRECT_STD(STDIN_FILENO, "r"); + break; default: array = wordListToWordArray(list); signal = loadRightCommand(array); @@ -308,14 +342,24 @@ WordList * parseWordList(WordList *list, shell_operator *an_operator) { (char*) "\\|\\|", (char*) "&&", (char*) "\\|", - (char*) "&" + (char*) "&", + (char*) "2>>", + (char*) ">>", + (char*) "2>", + (char*) ">", + (char*) "<[^<]" }; shell_operator op[] = { OR, REVERSE_AND, AND, PIPE, - BACKGROUND_PROCESS + BACKGROUND_PROCESS, + REDIRECT_STDERR_APPEND, + REDIRECT_STDOUT_APPEND, + REDIRECT_STDERR_ERASE, + REDIRECT_STDOUT_ERASE, + REDIRECT_STDIN }; WordList *newList = NULL; int max = sizeof(op_str) / sizeof(char*); diff --git a/fish_shell/fish_types.h b/fish_shell/fish_types.h index 51f9e24..d16b95d 100644 --- a/fish_shell/fish_types.h +++ b/fish_shell/fish_types.h @@ -20,7 +20,12 @@ typedef enum { BACKGROUND_PROCESS, AND, OR, - REVERSE_AND + REVERSE_AND, + REDIRECT_STDOUT_ERASE, + REDIRECT_STDOUT_APPEND, + REDIRECT_STDERR_ERASE, + REDIRECT_STDERR_APPEND, + REDIRECT_STDIN } shell_operator ; typedef enum {