Răsfoiți Sursa

:tada: Ajout gestion erreur

Arthur Brandao 6 ani în urmă
părinte
comite
aa3aed62fc
4 a modificat fișierele cu 278 adăugiri și 2 ștergeri
  1. 194 0
      Serveur/error.c
  2. 82 0
      Serveur/error.h
  3. 1 1
      Serveur/json.h
  4. 1 1
      Serveur/makefile

+ 194 - 0
Serveur/error.c

@@ -0,0 +1,194 @@
+/* 
+ * File:   error.c
+ * Author: Arthur Brandao
+ *
+ * Created on 8 novembre 2018
+ */
+#define _POSIX_C_SOURCE 200809L
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.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"
+};
+Error error;
+
+/* --- Fonctions de la structure --- */
+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(fd == 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;
+    error.print = NULL;
+    error.printadd = 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(int status, const char* format, ...){
+    va_list arg;
+    va_start(arg, format);
+    vfprintf(stdout, format, arg);
+    va_end(arg);
+    error.exit_status(status);
+}
+
+void add(const char* format, ...){
+    va_list arg;
+    va_start(arg, format);
+    vfprintf(stderr, format, arg);
+    va_end(arg);
+}
+
+void printerr(const char* format, ...){
+    va_list arg;
+    va_start(arg, format);
+    vdprintf(error.errfd, format, arg);
+    va_end(arg);
+}
+
+void printadd(const char* format, ...){
+    va_list arg;
+    va_start(arg, format);
+    vdprintf(error.errfd, format, arg);
+    vfprintf(stderr, format, arg);
+    va_end(arg);
+}
+
+/* --- 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;
+}
+
+int redirect_fd2(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 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;
+    //Si il y a deja un log
+    if(error.init){
+        //On le ferme
+        error.end();
+    }
+    //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;
+    error.print = printerr;
+    error.printadd = printadd;
+    //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;
+}

+ 82 - 0
Serveur/error.h

@@ -0,0 +1,82 @@
+/* 
+ * 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 SENONE 0
+
+/* --- 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)(int, const char*, ...); //Termine le programme avec un status utilisateur et un message dans la sortie standard
+    void (*add)(const char*, ...); //Ajoute un message dans le log
+    void (*print)(const char*, ...); //Affiche un message dans la sortie d'erreur
+    void (*printadd)(const char*, ...); //Fonction print + add
+}Error;
+
+/* --- Extern --- */
+extern int serrno; //Server 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 fermé par la fonction
+ * @return int Le nouveau fd du fichier qui avait le fd d'accueil
+ */
+int redirect_fd(int, int);
+
+/**
+ * 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_fd2(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 */
+

+ 1 - 1
Serveur/json.h

@@ -9,7 +9,7 @@
 
 /* --- Include --- */
 #include "str.h"
-#include "boolean.h"
+#include "constante.h"
 
 /* --- Constante --- */
 #define JSON_ERROR -1

+ 1 - 1
Serveur/makefile

@@ -3,7 +3,7 @@
 #
 
 EXEC = main
-OBJETS = str.o json_parser.o json_encoder.o
+OBJETS = str.o json_parser.o json_encoder.o error.o
 NOM_PROJET = Porjet Reseau
 
 #