|
@@ -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;
|
|
|
+}
|