From faf692aea663ee638674dcc6bb46dcb0f73f82b4 Mon Sep 17 00:00:00 2001
From: rick <rick@gnous.eu>
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 <string.h>
#include <unistd.h>
#include <errno.h>
+//#include <sys/types.h>
+#include <signal.h>
+
+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 <unistd.h>
+
#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 <unistd.h>
#include <errno.h>
#include <sys/wait.h>
+#include <signal.h>
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;
}