Эх сурвалжийг харах

:sparkles: Structure de gestion d'erreur

Loquicom 6 жил өмнө
parent
commit
b52ef8d41d
3 өөрчлөгдсөн 145 нэмэгдсэн , 9 устгасан
  1. 105 0
      error.c
  2. 31 3
      error.h
  3. 9 6
      mysh.c

+ 105 - 0
error.c

@@ -8,6 +8,10 @@
 #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 --- */
@@ -23,6 +27,60 @@ char* serrlib[] = {
     "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){
@@ -45,4 +103,51 @@ int redirect_fd(int fd1, int fd2){
     }
     //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;
 }

+ 31 - 3
error.h

@@ -9,14 +9,15 @@
 #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, "str"\n", __LINE__)
+#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, "str" : %s\n", __LINE__, strserror(serrno))
+#define addserror(str) fprintf(stderr, "Erreur dans le fichier "__FILE__" ligne %d, %s : %s\n", __LINE__, str, strserror(serrno))
 
 /* --- Constantes Generales --- */
 #define ERR -1
@@ -33,10 +34,25 @@
 #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 errno;
 extern int serrno; //Shell Errno
 extern char* serrlib[];
+extern Error error;
 
 /* --- Fonctions --- */
 /**
@@ -47,5 +63,17 @@ extern char* serrlib[];
  */
 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 */
 

+ 9 - 6
mysh.c

@@ -16,6 +16,9 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
+/* --- Extern --- */
+extern Error error;
+
 /* --- Fonctions privées --- */
 void test_write() {
     char* a = "azerty\n";
@@ -42,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[BUFFER_SIZE];
     int a;
+    //Initialisation erreur
+    error_finit("mysh.log");
     //Recup ligne
     //printf("%s\n", fgets(str, 500, stdin));&
     memset(str, 0, 500);
@@ -56,13 +60,13 @@ int main(int argc, char* argv[]) {
     a = parse_line(&ct, str);
     if(a == SHELL_ERR){
         addserror("Erreur lors du parse de la ligne");
-        exit(EXIT_FAILURE);
+        error.exit_err();
     }
     //Parse les commandes
     a = parse_all_command(&ct);
     if(a == SHELL_FAIL){
         addserror("Erreur lors du parse des commandes");
-        exit(EXIT_FAILURE);
+        error.exit_err();
     }
     //Affiche resultat
     for (int i = 0; i < ct.length; i++) {
@@ -75,8 +79,7 @@ int main(int argc, char* argv[]) {
     }
     //Supprime
     clean_command(&ct);
-    return (EXIT_SUCCESS);
-
+    error.exit();
 }
 
 /* --- Commandes internes --- */