/* * File: error.c * Author: Arthur Brandao * * Created on 8 novembre 2018 */ #define _POSIX_C_SOURCE 200809L #include #include #include #include #include #include #include #include "str.h" #include "error.h" /* --- Extern --- */ int serrno = 0; char* serrlib[] = { "Reussite", "Erreur lors de la creation de la socket", "Erreur lors du bind de la socket", "Erreur lors l'acceptation d'une connexion TCP", "Erreur lors de la reception des données", "Erreur lors de l'envoi des données", "Erreur lors de la fermeture de la socket", "Erreur mauvais type de socket" }; 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; }