From faf692aea663ee638674dcc6bb46dcb0f73f82b4 Mon Sep 17 00:00:00 2001 From: rick Date: Mon, 22 Feb 2021 15:48:35 +0100 Subject: [PATCH] Gestion du ctrl d & proto pour ctrl c, close #3 --- src/boitoutil/essential_shell.c | 12 ++++++ src/boitoutil/essential_shell.h | 5 +++ src/boitoutil/parser.c | 67 +++++++++++++++++++++++++++++---- src/boitoutil/parser.h | 3 +- src/shellOpt.c | 34 ++++++++--------- 5 files changed, 95 insertions(+), 26 deletions(-) diff --git a/src/boitoutil/essential_shell.c b/src/boitoutil/essential_shell.c index 53fca43..cc11047 100644 --- a/src/boitoutil/essential_shell.c +++ b/src/boitoutil/essential_shell.c @@ -13,6 +13,10 @@ #include #include #include +//#include +#include + +pid_t pid; /** * native_command(): vérifie si la commande entrée par l’utilisateur @@ -66,6 +70,14 @@ void change_dir(char *dir) } } +void ctrl_c_handler() +{ + //kill(pid, SIGTERM); + //kill(pid, SIGKILL); + kill(getpid(), SIGCHLD); + printf("\n"); +} + /** * error(): gère les erreurs selon leur code et leur type * @code: code de l’erreur, voir les différents codes dans le fichier .h diff --git a/src/boitoutil/essential_shell.h b/src/boitoutil/essential_shell.h index 53d1eae..48c99fc 100644 --- a/src/boitoutil/essential_shell.h +++ b/src/boitoutil/essential_shell.h @@ -7,6 +7,8 @@ * @date 2021 */ +#include + #ifndef _ESSHELL_ # define _ESSHELL_ @@ -17,8 +19,11 @@ #define ERR_PIPE_CREATION 200 /* erreur lors de la création des pipes */ #define ERR_FORK 201 /* erreur lors du fork */ +extern pid_t pid; + int native_command(char *command[]); void change_dir(char *dir); +void ctrl_c_handler(); void error(int code, int type, char *message); #endif diff --git a/src/boitoutil/parser.c b/src/boitoutil/parser.c index 7dbcd28..25ade75 100644 --- a/src/boitoutil/parser.c +++ b/src/boitoutil/parser.c @@ -16,19 +16,30 @@ /** * get_input(): Permet de récupérer la saisie de l’utilisateur * - * Return: Entrée utilisateur + * Return: Entrée utilisateur ou NULL si ctrl d détecté */ char* get_input() { + int stop = 0; /* en cas de ctrl d */ char *buffer = (char *) calloc(MAX_LENGTH, sizeof(char)); buffer[0] = '\n'; - while (buffer[0] == '\n') + while (buffer[0] == '\n' && !stop) { printf("> "); - fgets(buffer, MAX_LENGTH, stdin); + if(fgets(buffer, MAX_LENGTH, stdin) == NULL) + stop++; } - buffer[strlen(buffer)-1] = '\0'; /* pour ne pas avoir un retour à la ligne */ + + if (stop) + { + free(buffer); + buffer = NULL; + putchar('\n'); /* pour un affichage propre */ + } + else + buffer[strlen(buffer)-1] = '\0'; /* pour ne pas avoir un retour à la ligne */ + return buffer; } @@ -39,12 +50,23 @@ char* get_input() * * Récupère l’entrée de l’utilisateur avant de la parser avec le caractère * find. Chaque string sera mise dans une case de args. + * + * Return: 0 si tout est OK, 1 sinon */ -void get_command(char *args[], char find) +int get_command(char *args[], char find) { + int ret = 0; char *user_input = get_input(); - parse_string(user_input, args, find); - free(user_input); + + if (user_input == NULL) + ret = 1; + else + { + parse_string(user_input, args, find); + free(user_input); + } + + return ret; } /** @@ -88,3 +110,34 @@ void parse_string(char *orig, char *dest[], char find) free(token); } + +/** + * detect_exit(): vérifie si la commande entrée est exit + * @command: la première commande entrée par l’utilisateur + * + * Return: 0 si ce n’est pas exit, 1 sinon + */ +int detect_exit(char *command) +{ + /* + * TODO c’est dégueulasse, à changer pour un truc plus propre + */ + char *str = malloc(MAX_LENGTH * sizeof(char)); + strcpy(str, command); + char find = ' '; + char *token = strtok(str, &find); + char *args[MAX_LENGTH]; + int ret = 0, i = 0; + while (token != NULL) + { + args[i] = token; + token = strtok(NULL, &find); + i++; + } + + if (i == 1 && !strcmp(args[0], "exit")) + ret++; + + free(token); + return ret; +} diff --git a/src/boitoutil/parser.h b/src/boitoutil/parser.h index 3e3ab7d..c4e3d93 100644 --- a/src/boitoutil/parser.h +++ b/src/boitoutil/parser.h @@ -11,7 +11,8 @@ # define _PARSER_H_ char* get_input(); -void get_command(char *args[], char find); +int get_command(char *args[], char find); void parse_string(char *args,char *commands[], char find); +int detect_exit(char *command); #endif diff --git a/src/shellOpt.c b/src/shellOpt.c index 75458ad..7b1e692 100644 --- a/src/shellOpt.c +++ b/src/shellOpt.c @@ -14,6 +14,7 @@ #include #include #include +#include int main() { @@ -27,9 +28,18 @@ int main() char *commands[MAX_LENGTH]; char *args[MAX_LENGTH]; - int pid, result, index = 0, end = 0; /* end permet de savoir quand s’arreter */ + int result, index = 0, end = 0; /* end permet de savoir quand s’arreter */ int my_pipe[2]; - setenv("HELLO", "test", 1); + + /* init pour la gestion du ctrl c */ + struct sigaction ctrc_handler; + ctrc_handler.sa_handler = ctrl_c_handler; + sigemptyset(&ctrc_handler.sa_mask); + ctrc_handler.sa_flags = 0; + + sigaction(SIGINT, &ctrc_handler, NULL); + + setenv("HELLO", "test", 1); /* juste un test */ if (pipe(my_pipe) == -1) error(ERR_PIPE_CREATION, FATAL_ERROR, NULL); @@ -40,9 +50,7 @@ int main() commands[i] = (char *) calloc(MAX_LENGTH, sizeof(char)); } - get_command(commands, '|'); - - while (strcmp(commands[0], "exit")) + while (!get_command(commands, '|') && !detect_exit(commands[0])) { while (commands[index] != NULL) { @@ -68,7 +76,7 @@ int main() else fclose(fdopen(my_pipe[0], "w")); /* si la commande est intermédiaire dans le pipe, on vide le buffer - * de sortie */ + * de sortie NE MARCHE PAS */ execvp(args[0], args); exit(errno); @@ -80,12 +88,10 @@ int main() { close(my_pipe[0]); close(my_pipe[1]); - waitpid(pid, &result, 0); } - else - wait(&result); + waitpid(pid, &result, 0); - if(WIFEXITED(result)) + if(WIFEXITED(result)) /* on récupère le code de retour pour afficher l’erreur */ error(WEXITSTATUS(result), NON_FATAL_ERROR, NULL); } @@ -106,16 +112,8 @@ int main() commands[i] = (char *) calloc(MAX_LENGTH, sizeof(char)); } - get_command(commands, '|'); if (pipe(my_pipe) == -1) - { - for (int i = 0; i < MAX_LENGTH; i++) - { - free(args[i]); - free(commands[i]); - } error(ERR_PIPE_CREATION, FATAL_ERROR, NULL); - } index = 0; }