소스 검색

Merge pull request #10 from Loquicom/error

Ajout gestion d'erreur
Loquicom 6 년 전
부모
커밋
f96e4a5a7c
9개의 변경된 파일296개의 추가작업 그리고 24개의 파일을 삭제
  1. 2 1
      .gitignore
  2. 1 1
      constante.h
  3. 153 0
      error.c
  4. 79 0
      error.h
  5. 5 3
      makefile
  6. 25 10
      mysh.c
  7. 28 6
      parser.c
  8. 0 1
      parser.h
  9. 3 2
      wildcard.c

+ 2 - 1
.gitignore

@@ -52,4 +52,5 @@ Mkfile.old
 dkms.conf
 /.directory
 /nbproject
-/mysh
+/mysh
+/mysh.log

+ 1 - 1
constante.h

@@ -9,7 +9,7 @@
 #define CONSTANTE_H
 
 /* --- General --- */
-#define ERR -1
+#define BUFFER_SIZE 512
 #define SHELL_ERR -1
 #define SHELL_FAIL 0
 #define SHELL_OK 1

+ 153 - 0
error.c

@@ -0,0 +1,153 @@
+/* 
+ * File:   error.c
+ * Author: Arthur Brandao
+ *
+ * Created on 8 novembre 2018
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "str.h"
+#include "error.h"
+
+/* --- Extern --- */
+int serrno = 0;
+char* serrlib[] = {
+    "Reussite",
+    "Ligne de commande mal terminée",
+    "& inattendue",
+    "Impossible d'ouvrir/créer le fichier pour la redirection",
+    "Type de redirection incorrect",
+    "Redirection Incorrect",
+    "Command incorrect",
+    "Analyse wildcard impossible",
+    "Echec ajout wildcard dans argv"
+};
+Error error;
+
+/* --- Fonctions privée --- */
+void end(){
+    time_t temps;
+    int fd;
+    //Ecriture derniere ligne
+    temps = time(NULL) - error.start;
+    fprintf(stderr, "----- Fin log processus %d (temps en seconde : %ld) -----\n", getpid(), temps);
+    //On remet la sortie standard des erreurs
+    fd = redirect_fd(STDERR_FILENO, error.errfd);
+    if(error.errfd == ERR){
+        adderror("Impossible de rediriger la sortie d'erreur standard");
+        return;
+    }
+    //Fermeture du fichier
+    if(close(fd) == ERR){
+        addperror("Erreur pendant la fermeture du fichier de log");
+        return;
+    }
+    //Nettoyage memoire
+    free(error.filename);
+    error.start = 0;
+    error.end = NULL;
+    error.exit = NULL;
+    error.exit_err = NULL;
+    error.exit_status = NULL;
+    error.exit_msg = NULL;
+    error.add = NULL;
+    //On indique que la structure est non inialisée
+    error.init = 0;
+}
+
+void exit_status(int status){
+    error.end();
+    exit(status);
+}
+
+void exit_ok(){
+    error.exit_status(EXIT_SUCCESS);
+}
+
+void exit_err(){
+    error.exit_status(EXIT_FAILURE);
+}
+
+void exit_msg(char* msg, int status){
+    printf("%s", msg);
+    error.exit_status(status);
+}
+
+void add(char* msg){
+    fprintf(stderr, "%s\n", msg);
+}
+
+/* --- Fonctions publiques --- */
+int redirect_fd(int fd1, int fd2){
+    int tmpfd;
+    //On duplique le 1er fd
+    tmpfd = dup(fd1);
+    if(tmpfd == ERR){
+        addperror("Erreur pendant la duplication");
+        return ERR;
+    }
+    //On fait en sorte que fd1 soit lié au fichier de fd2
+    if(dup2(fd2, fd1) == ERR){
+        addperror("Erreur pendant le changement de fd");
+        return ERR;
+    }
+    //On ferme l'ancien fd2
+    if(close(fd2) == ERR){
+        addperror("Erreur pendant la fermeture de fd2");
+        return ERR;
+    }
+    //On retourne le nouveau fd de fd1
+    return tmpfd;
+}
+
+void error_init(){
+    //Creation nom fichier puis initialisation
+    char filename[19];
+    sprintf(filename, "err-%ld.log", time(NULL));
+    error_finit(filename);
+}
+
+void error_finit(const char* filename){
+    extern Error error;
+    int fd, length;
+    //Ouverture fichier
+    fd = open(filename, O_CREAT | O_RDWR, S_IRWXU);
+    if(fd == ERR){
+        addperror("Erreur lors de l'ouverture du fichier de log");
+        return;
+    }
+    //On se place à la fin du fichier
+    if(lseek(fd, 0L, SEEK_END) == ERR){
+        addperror("Erreur lors du deplacement dans le fichier");
+        return;
+    }
+    //Changement de la sortie d'erreur standard
+    error.errfd = redirect_fd(STDERR_FILENO, fd);
+    if(error.errfd == ERR){
+        adderror("Impossible de rediriger la sortie d'erreur standard");
+        return;
+    }
+    //Copie nom du fichier
+    length = strlen(filename);
+    error.filename = malloc(sizeof(char) * (length + 1));
+    memset(error.filename, 0, length + 1);
+    strncpy(error.filename, filename, length);
+    //Timestamp de debut
+    error.start = time(NULL);
+    //Ajout fonctions
+    error.end = end;
+    error.exit = exit_ok;
+    error.exit_err = exit_err;
+    error.exit_status = exit_status;
+    error.exit_msg = exit_msg;
+    error.add = add;
+    //Ecriture 1er ligne
+    fprintf(stderr, "----- Log processus %d (timestamp : %ld) -----\n", getpid(), error.start);
+    //On indique que l'inialisation a eu lieu
+    error.init = 1;
+}

+ 79 - 0
error.h

@@ -0,0 +1,79 @@
+/* 
+ * File:   error.h
+ * Author: Arthur Brandao
+ *
+ * Created on 8 novembre 2018
+ */
+
+#ifndef ERROR_H
+#define ERROR_H
+
+#include <stdio.h>
+#include <time.h>
+
+
+/* --- Macro --- */
+#define serror(str) fprintf(stderr, str" : %s\n", serrlib[serrno])
+#define strserror(index) serrlib[index]
+#define adderror(str) fprintf(stderr, "Erreur dans le fichier "__FILE__" ligne %d, %s\n", __LINE__, str)
+#define addperror(str) fprintf(stderr, "Erreur dans le fichier "__FILE__" ligne %d, ", __LINE__); perror(str" ")
+#define addserror(str) fprintf(stderr, "Erreur dans le fichier "__FILE__" ligne %d, %s : %s\n", __LINE__, str, strserror(serrno))
+
+/* --- Constantes Generales --- */
+#define ERR -1
+#define FAIL 0
+#define SUCCESS 1
+
+/* --- Constantes Erreurs --- */
+#define SEBADEND 1
+#define SEBADET 2
+#define SEOPENF 3
+#define SEREDIRTYPE 4
+#define SEBADREDIR 5
+#define SEBADCMD 6
+#define SEWC 7
+#define SEADDWC 8
+
+/* --- Structure --- */
+typedef struct{
+    int init; //Initialisée ou non
+    char* filename; //Nom du fichier
+    int errfd; //Descripteur de fichier de la sortie standard des erreurs
+    time_t start; //TImestamp de debut
+    /* Fonctions */
+    void (*end)(); //Termine le gestionnaire d'erreur
+    void (*exit)(); //Termine le programme avec EXIT_SUCCESS
+    void (*exit_err)(); //Termine le programme avec EXIT_FAILURE
+    void (*exit_status)(int); //Termine le programme avec un status utilisateur
+    void (*exit_msg)(char*, int); //Termine le programme avec un status utilisateur et un message dans la sortie standard
+    void (*add)(char*); //Ajoute un message dans le log
+}Error;
+
+/* --- Extern --- */
+extern int serrno; //Shell Errno
+extern char* serrlib[];
+extern Error error;
+
+/* --- Fonctions --- */
+/**
+ * Change un fd par la valeur d'un autre fd
+ * @param int fd accueil
+ * @param int fd source
+ * @return int Le nouveau fd du fichier qui avait le fd d'accueil
+ */
+int redirect_fd(int, int);
+
+/**
+ * Initialise la gestion d'erreur
+ * Le log sera nommé err-timestamp.log
+ */
+void error_init();
+
+/**
+ * Initialise le log d'erreur
+ * @param char* Le nom du fichier de log
+ */
+void error_finit(const char*);
+
+#endif /* ERROR_H */
+

+ 5 - 3
makefile

@@ -3,7 +3,7 @@
 #
 
 EXEC = mysh
-OBJETS = str.o parser.o wildcard.o
+OBJETS = error.o str.o parser.o wildcard.o
 NOM_PROJET = mini-shell
 
 #
@@ -88,6 +88,8 @@ archive: clean
 	@echo "Termine."
 
 # DEPENDANCES
+error.o: error.c error.h
 str.o: str.c str.h
-parser.o: parser.c parser.h constante.h str.h
-mysh.o: mysh.c parser.h constante.h str.h mysh.h
+parser.o: parser.c error.h wildcard.h constante.h parser.h str.h
+wildcard.o: wildcard.c error.h wildcard.h constante.h
+mysh.o: mysh.c error.h parser.h constante.h str.h mysh.h

+ 25 - 10
mysh.c

@@ -7,9 +7,18 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <fcntl.h>
+#include "error.h"
+#include "str.h"
 #include "parser.h"
 #include "mysh.h"
 
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/* --- Extern --- */
+extern Error error;
+
 /* --- Fonctions privées --- */
 void test_write() {
     char* a = "azerty\n";
@@ -19,9 +28,9 @@ void test_write() {
 
 /* --- Fonctions utilitaires --- */
 void show_current_dir(const char* before, const char* after) {
-    char buffer[512];
+    char buffer[BUFFER_SIZE];
     if (getcwd(buffer, sizeof (buffer)) == NULL) {
-        perror("Erreur getcwd() : ");
+        addperror("Erreur getcwd()");
     } else {
         if(before == NULL && after == NULL){
             printf("%s", buffer);
@@ -36,11 +45,12 @@ void show_current_dir(const char* before, const char* after) {
 }
 
 /* --- Main --- */
-int main(int argc, char* argv[]) {
-    
+int main(int argc, char* argv[]) { 
     CommandTab ct;
-    char str[500];
+    char str[BUFFER_SIZE];
     int a;
+    //Initialisation erreur
+    error_finit("mysh.log");
     //Recup ligne
     //printf("%s\n", fgets(str, 500, stdin));&
     memset(str, 0, 500);
@@ -48,10 +58,16 @@ int main(int argc, char* argv[]) {
     printf("%s\n", str);
     //Separe les commandes
     a = parse_line(&ct, str);
-    printf("Result : %d\n\n", a);
+    if(a == SHELL_ERR){
+        addserror("Erreur lors du parse de la ligne");
+        error.exit_err();
+    }
     //Parse les commandes
     a = parse_all_command(&ct);
-    printf("Result : %d\n\n", a);
+    if(a == SHELL_FAIL){
+        addserror("Erreur lors du parse des commandes");
+        error.exit_err();
+    }
     //Affiche resultat
     for (int i = 0; i < ct.length; i++) {
         Command* c = ct.cmd[i];
@@ -63,8 +79,7 @@ int main(int argc, char* argv[]) {
     }
     //Supprime
     clean_command(&ct);
-    return (EXIT_SUCCESS);
-
+    error.exit();
 }
 
 /* --- Commandes internes --- */
@@ -76,7 +91,7 @@ void cd(int argc, char** argv) {
         //Si aucun argument on vas à la racine
         if (argc == 1) {
             if (chdir("/") == ERR) {
-                perror("Erreur chdir() : ");
+                addperror("Erreur chdir()");
             }
         }            //Sinon on va dans le dossier indiqué par l'utilisateur
         else {

+ 28 - 6
parser.c

@@ -12,9 +12,14 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include "error.h"
+#include "str.h"
 #include "wildcard.h"
 #include "parser.h"
 
+/* --- Extern --- */
+extern int serrno;
+
 /* --- Fonctions privées --- */
 /**
  * Indique le nombre de commande dans une ligne
@@ -34,12 +39,14 @@ int nb_commands(char* line){
         else if(*line == '|'){
             //Verif que ce n'est pas le dernier carac
             if(*(line + 1) == '\0'){
+                serrno = SEBADEND;
                 return SHELL_ERR;
             }
             //Si un || on avance de 1 en plus
             else if(*(line + 1) == '|'){
                 //Si à la fin de la chaine
                 if(*(line + 2) == '\0'){
+                    serrno = SEBADEND;
                     return SHELL_ERR;
                 }
                 line++;
@@ -55,6 +62,7 @@ int nb_commands(char* line){
             }
             //Sinon il doit y avoir un vide pour etre le & du bck ou un > avant
             else if(*(line + 1) != '\0' && *(line - 1) != '>'){
+                serrno = SEBADET;
                 return SHELL_ERR;
             }
         }
@@ -139,7 +147,8 @@ int set_io(Command* c, char* filename, int redir){
     //Ouverture du fichier
     file = open(filename, O_CREAT | O_RDWR, S_IRWXU);
     if(file == ERR){
-        perror("Erreur lors de l'ouverture du fichier pour la redirection : ");
+        addperror("Erreur lors de l'ouverture du fichier pour la redirection");
+        serrno = SEOPENF;
         return SHELL_ERR;
     }
     //Analyse dans quel descripteur il doit etre mis
@@ -149,7 +158,7 @@ int set_io(Command* c, char* filename, int redir){
             if(c->input != STDIN){
                 //On le ferme
                 if(close(c->input) == -1){
-                    perror("Erreur lors de la fermeture de l'ancien fichier de redirection : ");
+                    addperror("Erreur lors de la fermeture de l'ancien fichier de redirection");
                 }
             }
             //Set nouveau fichier
@@ -161,7 +170,7 @@ int set_io(Command* c, char* filename, int redir){
             if(c->output != STDOUT){
                 //On le ferme
                 if(close(c->output) == -1){
-                    perror("Erreur lors de la fermeture de l'ancien fichier de redirection : ");
+                    addperror("Erreur lors de la fermeture de l'ancien fichier de redirection");
                 }
             }
             c->output = file;
@@ -175,7 +184,7 @@ int set_io(Command* c, char* filename, int redir){
             if(c->error != STDERR){
                 //On le ferme
                 if(close(c->error) == -1){
-                    perror("Erreur lors de la fermeture de l'ancien fichier de redirection : ");
+                    addperror("Erreur lors de la fermeture de l'ancien fichier de redirection");
                 }
             }
             c->error = file;
@@ -189,13 +198,13 @@ int set_io(Command* c, char* filename, int redir){
             if(c->output != STDOUT){
                 //On le ferme
                 if(close(c->output) == -1){
-                    perror("Erreur lors de la fermeture de l'ancien fichier de redirection : ");
+                    addperror("Erreur lors de la fermeture de l'ancien fichier de redirection");
                 }
             }
             if(c->error != STDERR){
                 //On le ferme
                 if(close(c->error) == -1){
-                    perror("Erreur lors de la fermeture de l'ancien fichier de redirection : ");
+                    addperror("Erreur lors de la fermeture de l'ancien fichier de redirection");
                 }
             }
             c->output = file;
@@ -206,6 +215,7 @@ int set_io(Command* c, char* filename, int redir){
             }
             break;
         default :
+            serrno = SEREDIRTYPE;
             return SHELL_ERR;
     }
     //Si on arrive ici tous est ok
@@ -229,6 +239,7 @@ int set_redirection(Command* c){
             if(*buffer == '<'){
                 //Si il n'y a rien apres
                 if(!(*(buffer + 1))){
+                    serrno = SEBADREDIR;
                     return SHELL_ERR;
                 }
                 buffer++;
@@ -239,6 +250,7 @@ int set_redirection(Command* c){
             else if (*buffer == '>'){
                 //Si il n'y a rien apres
                 if(!(*(buffer + 1))){
+                    serrno = SEBADREDIR;
                     return SHELL_ERR;
                 } else {
                     buffer++;
@@ -246,6 +258,7 @@ int set_redirection(Command* c){
                     if(*buffer == '>'){
                         //Si il n'y a rien apres
                         if(!(*(buffer + 1))){
+                            serrno = SEBADREDIR;
                             return SHELL_ERR;
                         } else {
                             buffer++;
@@ -253,6 +266,7 @@ int set_redirection(Command* c){
                             if(*buffer == '&'){
                                 //Si il n'y a rien apres
                                 if(!(*(buffer + 1))){
+                                    serrno = SEBADREDIR;
                                     return SHELL_ERR;
                                 }
                                 buffer++;
@@ -268,6 +282,7 @@ int set_redirection(Command* c){
                     else if(*buffer == '&'){
                         //Si il n'y a rien apres
                         if(!(*(buffer + 1))){
+                            serrno = SEBADREDIR;
                             return SHELL_ERR;
                         }
                         redir = SHELLRE_ALL;
@@ -285,6 +300,7 @@ int set_redirection(Command* c){
                 buffer++;
                 //Si il n'y a rien apres
                 if(!(*(buffer + 1))){
+                    serrno = SEBADREDIR;
                     return SHELL_ERR;
                 } else {
                     buffer++;
@@ -293,6 +309,7 @@ int set_redirection(Command* c){
                         buffer++;
                         //Si il n'y a rien apres
                         if(!(*(buffer + 1))){
+                            serrno = SEBADREDIR;
                             return SHELL_ERR;
                         }
                         redir = SHELLR_ERR;
@@ -323,6 +340,7 @@ int set_redirection(Command* c){
                 return finCmd + 1;
             }
             //Sinon on est dans un redirection non terminée
+            serrno = SEBADCMD;
             return SHELL_ERR;
         }
         //Regarde si le nom du fichier est entre ""
@@ -345,6 +363,7 @@ int set_redirection(Command* c){
         }
         //Si fin de la commande et guillemet alors erreur
         if(!(*buffer) && guillemet){
+            serrno = SEBADCMD;
             return SHELL_ERR;
         }
         //Retire guillement si besoin
@@ -394,6 +413,7 @@ int split_command(Command* c, char* cmd){
             if(*cmd == '"'){
                 //Verif que ce n'est pas la fin
                 if(!(*(cmd + 1))){
+                    serrno = SEBADCMD;
                     return SHELL_ERR;
                 }
                 cmd++;
@@ -522,11 +542,13 @@ int parse_command(Command* c){
             nbWildcard = wildcard(c->argv[i], nbWildcard, wildcardTab);
             //Verif retour
             if(nbWildcard == ERR){
+                serrno = SEWC;
                 return SHELL_ERR;
             }
             //Ajoute les wildcard dans argv (le +1 est la pour garder le NULL à la fin)
             c->argv = insert_array(i, c->argv, c->argc + 1, wildcardTab, nbWildcard, &res);
             if(res == ERR){
+                serrno = SEADDWC;
                 return SHELL_ERR;
             }
             c->argc = res - 1;  //On ne compte pas le NULL final

+ 0 - 1
parser.h

@@ -10,7 +10,6 @@
 
 /* --- Include --- */
 #include "constante.h"
-#include "str.h"
 
 /* --- Structure --- */
 typedef struct {

+ 3 - 2
wildcard.c

@@ -15,6 +15,7 @@
 #include <unistd.h>
 #include <fnmatch.h>
 #include <string.h>
+#include "error.h"
 #include "wildcard.h"
 
 int wildcard_result(const char* seq) {
@@ -24,7 +25,7 @@ int wildcard_result(const char* seq) {
     //Recup la liste des fichiers dans le dossier courant
     nbFile = scandir(".", &namelist, 0, alphasort);
     if (nbFile < 0) {
-        perror("scandir() : ");
+        addperror("Erreur scandir()");
         return ERR;
     }
     //Parcours chaque fichier pour compter le nombre de resultat
@@ -57,7 +58,7 @@ int wildcard(const char* seq, int size, char** result) {
     //Recup la liste des fichiers dans le dossier courant
     nbFile = scandir(".", &namelist, 0, alphasort);
     if (nbFile < 0) {
-        perror("scandir() : ");
+        addperror("Erreur scandir()");
         return ERR;
     }
     //Parcours chaque fichier pour ajouter les resultats à result