/* * 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", "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 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; }