error.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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(char* msg, int status){
  74. printf("%s", msg);
  75. error.exit_status(status);
  76. }
  77. void add(const char* format, ...){
  78. va_list arg;
  79. va_start(arg, format);
  80. vfprintf(stderr, format, arg);
  81. va_end(arg);
  82. }
  83. void printerr(const char* format, ...){
  84. va_list arg;
  85. va_start(arg, format);
  86. vdprintf(error.errfd, format, arg);
  87. va_end(arg);
  88. }
  89. void printadd(const char* format, ...){
  90. va_list arg;
  91. va_start(arg, format);
  92. vdprintf(error.errfd, format, arg);
  93. vfprintf(stderr, format, arg);
  94. va_end(arg);
  95. }
  96. /* --- Fonctions publiques --- */
  97. int redirect_fd(int fd1, int fd2){
  98. int tmpfd;
  99. //On duplique le 1er fd
  100. tmpfd = dup(fd1);
  101. if(tmpfd == ERR){
  102. addperror("Erreur pendant la duplication");
  103. return ERR;
  104. }
  105. //On fait en sorte que fd1 soit lié au fichier de fd2
  106. if(dup2(fd2, fd1) == ERR){
  107. addperror("Erreur pendant le changement de fd");
  108. return ERR;
  109. }
  110. //On ferme l'ancien fd2
  111. if(close(fd2) == ERR){
  112. addperror("Erreur pendant la fermeture de fd2");
  113. return ERR;
  114. }
  115. //On retourne le nouveau fd de fd1
  116. return tmpfd;
  117. }
  118. void error_init(){
  119. //Creation nom fichier puis initialisation
  120. char filename[19];
  121. sprintf(filename, "err-%ld.log", time(NULL));
  122. error_finit(filename);
  123. }
  124. void error_finit(const char* filename){
  125. extern Error error;
  126. int fd, length;
  127. //Ouverture fichier
  128. fd = open(filename, O_CREAT | O_RDWR, S_IRWXU);
  129. if(fd == ERR){
  130. addperror("Erreur lors de l'ouverture du fichier de log");
  131. return;
  132. }
  133. //On se place à la fin du fichier
  134. if(lseek(fd, 0L, SEEK_END) == ERR){
  135. addperror("Erreur lors du deplacement dans le fichier");
  136. return;
  137. }
  138. //Changement de la sortie d'erreur standard
  139. error.errfd = redirect_fd(STDERR_FILENO, fd);
  140. if(error.errfd == ERR){
  141. adderror("Impossible de rediriger la sortie d'erreur standard");
  142. return;
  143. }
  144. //Copie nom du fichier
  145. length = strlen(filename);
  146. error.filename = malloc(sizeof(char) * (length + 1));
  147. memset(error.filename, 0, length + 1);
  148. strncpy(error.filename, filename, length);
  149. //Timestamp de debut
  150. error.start = time(NULL);
  151. //Ajout fonctions
  152. error.end = end;
  153. error.exit = exit_ok;
  154. error.exit_err = exit_err;
  155. error.exit_status = exit_status;
  156. error.exit_msg = exit_msg;
  157. error.add = add;
  158. error.print = printerr;
  159. error.printadd = printadd;
  160. //Ecriture 1er ligne
  161. fprintf(stderr, "----- Log processus %d (timestamp : %ld) -----\n", getpid(), error.start);
  162. //On indique que l'inialisation a eu lieu
  163. error.init = 1;
  164. }