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