error.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * File: error.c
  3. * Author: Arthur Brandao
  4. *
  5. * Created on 8 novembre 2018
  6. */
  7. #define _POSIX_C_SOURCE 200809L
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <stdarg.h>
  11. #include <unistd.h>
  12. #include <fcntl.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include "str.h"
  16. #include "error.h"
  17. /* --- Extern --- */
  18. int serrno = 0;
  19. char* serrlib[] = {
  20. "Reussite",
  21. "Ligne de commande mal terminée",
  22. "& inattendue",
  23. "Impossible d'ouvrir/créer le fichier pour la redirection",
  24. "Type de redirection incorrect",
  25. "Redirection Incorrect",
  26. "Command incorrect",
  27. "Analyse wildcard impossible",
  28. "Echec ajout wildcard dans argv"
  29. };
  30. Error error;
  31. /* --- Fonctions de la structure --- */
  32. void end(){
  33. time_t temps;
  34. int fd;
  35. //Ecriture derniere ligne
  36. temps = time(NULL) - error.start;
  37. fprintf(stderr, "----- Fin log processus %d (temps en seconde : %ld) -----\n", getpid(), temps);
  38. //On remet la sortie standard des erreurs
  39. fd = redirect_fd(STDERR_FILENO, error.errfd);
  40. if(error.errfd == ERR){
  41. adderror("Impossible de rediriger la sortie d'erreur standard");
  42. return;
  43. }
  44. //Fermeture du fichier
  45. if(close(fd) == ERR){
  46. addperror("Erreur pendant la fermeture du fichier de log");
  47. return;
  48. }
  49. //Nettoyage memoire
  50. free(error.filename);
  51. error.start = 0;
  52. error.end = NULL;
  53. error.exit = NULL;
  54. error.exit_err = NULL;
  55. error.exit_status = NULL;
  56. error.exit_msg = NULL;
  57. error.add = NULL;
  58. error.print = NULL;
  59. error.printadd = NULL;
  60. //On indique que la structure est non inialisée
  61. error.init = 0;
  62. }
  63. void exit_status(int status){
  64. error.end();
  65. exit(status);
  66. }
  67. void exit_ok(){
  68. error.exit_status(EXIT_SUCCESS);
  69. }
  70. void exit_err(){
  71. error.exit_status(EXIT_FAILURE);
  72. }
  73. void exit_msg(int status, const char* format, ...){
  74. va_list arg;
  75. va_start(arg, format);
  76. vfprintf(stdout, format, arg);
  77. va_end(arg);
  78. error.exit_status(status);
  79. }
  80. void add(const char* format, ...){
  81. va_list arg;
  82. va_start(arg, format);
  83. vfprintf(stderr, format, arg);
  84. va_end(arg);
  85. }
  86. void printerr(const char* format, ...){
  87. va_list arg;
  88. va_start(arg, format);
  89. vdprintf(error.errfd, format, arg);
  90. va_end(arg);
  91. }
  92. void printadd(const char* format, ...){
  93. va_list arg;
  94. va_start(arg, format);
  95. vdprintf(error.errfd, format, arg);
  96. vfprintf(stderr, format, arg);
  97. va_end(arg);
  98. }
  99. /* --- Fonctions publiques --- */
  100. int redirect_fd(int fd1, int fd2){
  101. int tmpfd;
  102. //On duplique le 1er fd
  103. tmpfd = dup(fd1);
  104. if(tmpfd == ERR){
  105. addperror("Erreur pendant la duplication");
  106. return ERR;
  107. }
  108. //On fait en sorte que fd1 soit lié au fichier de fd2
  109. if(dup2(fd2, fd1) == ERR){
  110. addperror("Erreur pendant le changement de fd");
  111. return ERR;
  112. }
  113. //On ferme l'ancien fd2
  114. if(close(fd2) == ERR){
  115. addperror("Erreur pendant la fermeture de fd2");
  116. return ERR;
  117. }
  118. //On retourne le nouveau fd de fd1
  119. return tmpfd;
  120. }
  121. void error_init(){
  122. //Creation nom fichier puis initialisation
  123. char filename[19];
  124. sprintf(filename, "err-%ld.log", time(NULL));
  125. error_finit(filename);
  126. }
  127. void error_finit(const char* filename){
  128. extern Error error;
  129. int fd, length;
  130. //Si il y a deja un log
  131. if(error.init){
  132. //On le ferme
  133. error.end();
  134. }
  135. //Ouverture fichier
  136. fd = open(filename, O_CREAT | O_RDWR, S_IRWXU);
  137. if(fd == ERR){
  138. addperror("Erreur lors de l'ouverture du fichier de log");
  139. return;
  140. }
  141. //On se place à la fin du fichier
  142. if(lseek(fd, 0L, SEEK_END) == ERR){
  143. addperror("Erreur lors du deplacement dans le fichier");
  144. return;
  145. }
  146. //Changement de la sortie d'erreur standard
  147. error.errfd = redirect_fd(STDERR_FILENO, fd);
  148. if(error.errfd == ERR){
  149. adderror("Impossible de rediriger la sortie d'erreur standard");
  150. return;
  151. }
  152. //Copie nom du fichier
  153. length = strlen(filename);
  154. error.filename = malloc(sizeof(char) * (length + 1));
  155. memset(error.filename, 0, length + 1);
  156. strncpy(error.filename, filename, length);
  157. //Timestamp de debut
  158. error.start = time(NULL);
  159. //Ajout fonctions
  160. error.end = end;
  161. error.exit = exit_ok;
  162. error.exit_err = exit_err;
  163. error.exit_status = exit_status;
  164. error.exit_msg = exit_msg;
  165. error.add = add;
  166. error.print = printerr;
  167. error.printadd = printadd;
  168. //Ecriture 1er ligne
  169. fprintf(stderr, "----- Log processus %d (timestamp : %ld) -----\n", getpid(), error.start);
  170. //On indique que l'inialisation a eu lieu
  171. error.init = 1;
  172. }