Gestion du ctrl d & proto pour ctrl c, close #3
This commit is contained in:
parent
32b822555e
commit
faf692aea6
5 changed files with 95 additions and 26 deletions
|
@ -13,6 +13,10 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.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
|
* 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
|
* 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
|
* @code: code de l’erreur, voir les différents codes dans le fichier .h
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
* @date 2021
|
* @date 2021
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifndef _ESSHELL_
|
#ifndef _ESSHELL_
|
||||||
# define _ESSHELL_
|
# define _ESSHELL_
|
||||||
|
|
||||||
|
@ -17,8 +19,11 @@
|
||||||
#define ERR_PIPE_CREATION 200 /* erreur lors de la création des pipes */
|
#define ERR_PIPE_CREATION 200 /* erreur lors de la création des pipes */
|
||||||
#define ERR_FORK 201 /* erreur lors du fork */
|
#define ERR_FORK 201 /* erreur lors du fork */
|
||||||
|
|
||||||
|
extern pid_t pid;
|
||||||
|
|
||||||
int native_command(char *command[]);
|
int native_command(char *command[]);
|
||||||
void change_dir(char *dir);
|
void change_dir(char *dir);
|
||||||
|
void ctrl_c_handler();
|
||||||
void error(int code, int type, char *message);
|
void error(int code, int type, char *message);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,19 +16,30 @@
|
||||||
/**
|
/**
|
||||||
* get_input(): Permet de récupérer la saisie de l’utilisateur
|
* 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()
|
char* get_input()
|
||||||
{
|
{
|
||||||
|
int stop = 0; /* en cas de ctrl d */
|
||||||
char *buffer = (char *) calloc(MAX_LENGTH, sizeof(char));
|
char *buffer = (char *) calloc(MAX_LENGTH, sizeof(char));
|
||||||
buffer[0] = '\n';
|
buffer[0] = '\n';
|
||||||
|
|
||||||
while (buffer[0] == '\n')
|
while (buffer[0] == '\n' && !stop)
|
||||||
{
|
{
|
||||||
printf("> ");
|
printf("> ");
|
||||||
fgets(buffer, MAX_LENGTH, stdin);
|
if(fgets(buffer, MAX_LENGTH, stdin) == NULL)
|
||||||
|
stop++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 */
|
buffer[strlen(buffer)-1] = '\0'; /* pour ne pas avoir un retour à la ligne */
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,14 +50,25 @@ char* get_input()
|
||||||
*
|
*
|
||||||
* Récupère l’entrée de l’utilisateur avant de la parser avec le caractère
|
* 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.
|
* 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();
|
char *user_input = get_input();
|
||||||
|
|
||||||
|
if (user_input == NULL)
|
||||||
|
ret = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
parse_string(user_input, args, find);
|
parse_string(user_input, args, find);
|
||||||
free(user_input);
|
free(user_input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* parse_string(): Découpe la chaine orig et met chaque mot dans le tableau dest
|
* parse_string(): Découpe la chaine orig et met chaque mot dans le tableau dest
|
||||||
* @orig: chaine à découper
|
* @orig: chaine à découper
|
||||||
|
@ -88,3 +110,34 @@ void parse_string(char *orig, char *dest[], char find)
|
||||||
|
|
||||||
free(token);
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
# define _PARSER_H_
|
# define _PARSER_H_
|
||||||
|
|
||||||
char* get_input();
|
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);
|
void parse_string(char *args,char *commands[], char find);
|
||||||
|
int detect_exit(char *command);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
@ -27,9 +28,18 @@ int main()
|
||||||
char *commands[MAX_LENGTH];
|
char *commands[MAX_LENGTH];
|
||||||
char *args[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];
|
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)
|
if (pipe(my_pipe) == -1)
|
||||||
error(ERR_PIPE_CREATION, FATAL_ERROR, NULL);
|
error(ERR_PIPE_CREATION, FATAL_ERROR, NULL);
|
||||||
|
@ -40,9 +50,7 @@ int main()
|
||||||
commands[i] = (char *) calloc(MAX_LENGTH, sizeof(char));
|
commands[i] = (char *) calloc(MAX_LENGTH, sizeof(char));
|
||||||
}
|
}
|
||||||
|
|
||||||
get_command(commands, '|');
|
while (!get_command(commands, '|') && !detect_exit(commands[0]))
|
||||||
|
|
||||||
while (strcmp(commands[0], "exit"))
|
|
||||||
{
|
{
|
||||||
while (commands[index] != NULL)
|
while (commands[index] != NULL)
|
||||||
{
|
{
|
||||||
|
@ -68,7 +76,7 @@ int main()
|
||||||
else
|
else
|
||||||
fclose(fdopen(my_pipe[0], "w"));
|
fclose(fdopen(my_pipe[0], "w"));
|
||||||
/* si la commande est intermédiaire dans le pipe, on vide le buffer
|
/* si la commande est intermédiaire dans le pipe, on vide le buffer
|
||||||
* de sortie */
|
* de sortie NE MARCHE PAS */
|
||||||
|
|
||||||
execvp(args[0], args);
|
execvp(args[0], args);
|
||||||
exit(errno);
|
exit(errno);
|
||||||
|
@ -80,12 +88,10 @@ int main()
|
||||||
{
|
{
|
||||||
close(my_pipe[0]);
|
close(my_pipe[0]);
|
||||||
close(my_pipe[1]);
|
close(my_pipe[1]);
|
||||||
waitpid(pid, &result, 0);
|
|
||||||
}
|
}
|
||||||
else
|
waitpid(pid, &result, 0);
|
||||||
wait(&result);
|
|
||||||
|
|
||||||
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);
|
error(WEXITSTATUS(result), NON_FATAL_ERROR, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,16 +112,8 @@ int main()
|
||||||
commands[i] = (char *) calloc(MAX_LENGTH, sizeof(char));
|
commands[i] = (char *) calloc(MAX_LENGTH, sizeof(char));
|
||||||
}
|
}
|
||||||
|
|
||||||
get_command(commands, '|');
|
|
||||||
if (pipe(my_pipe) == -1)
|
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);
|
error(ERR_PIPE_CREATION, FATAL_ERROR, NULL);
|
||||||
}
|
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue