error.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. "Erreur lors de la creation de la socket",
  22. "Erreur lors du bind de la socket",
  23. "Erreur lors l'acceptation d'une connexion TCP",
  24. "Erreur lors de la reception des données",
  25. "Erreur lors de l'envoi des données",
  26. "Erreur lors de la fermeture de la socket",
  27. "Erreur mauvais type de socket",
  28. "Erreur connexion interrompue"
  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(fd == 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. int redirect_fd2(int fd1, int fd2){
  122. int tmpfd;
  123. //On duplique le 1er fd
  124. tmpfd = dup(fd1);
  125. if(tmpfd == ERR){
  126. addperror("Erreur pendant la duplication");
  127. return ERR;
  128. }
  129. //On fait en sorte que fd1 soit lié au fichier de fd2
  130. if(dup2(fd2, fd1) == ERR){
  131. addperror("Erreur pendant le changement de fd");
  132. return ERR;
  133. }
  134. //On retourne le nouveau fd de fd1
  135. return tmpfd;
  136. }
  137. void error_init(){
  138. //Creation nom fichier puis initialisation
  139. char filename[19];
  140. sprintf(filename, "err-%ld.log", time(NULL));
  141. error_finit(filename);
  142. }
  143. void error_finit(const char* filename){
  144. extern Error error;
  145. int fd, length;
  146. //Si il y a deja un log
  147. if(error.init){
  148. //On le ferme
  149. error.end();
  150. }
  151. //Ouverture fichier
  152. fd = open(filename, O_CREAT | O_RDWR, S_IRWXU);
  153. if(fd == ERR){
  154. addperror("Erreur lors de l'ouverture du fichier de log");
  155. return;
  156. }
  157. //On se place à la fin du fichier
  158. if(lseek(fd, 0L, SEEK_END) == ERR){
  159. addperror("Erreur lors du deplacement dans le fichier");
  160. return;
  161. }
  162. //Changement de la sortie d'erreur standard
  163. error.errfd = redirect_fd(STDERR_FILENO, fd);
  164. if(error.errfd == ERR){
  165. adderror("Impossible de rediriger la sortie d'erreur standard");
  166. return;
  167. }
  168. //Copie nom du fichier
  169. length = strlen(filename);
  170. error.filename = malloc(sizeof(char) * (length + 1));
  171. memset(error.filename, 0, length + 1);
  172. strncpy(error.filename, filename, length);
  173. //Timestamp de debut
  174. error.start = time(NULL);
  175. //Ajout fonctions
  176. error.end = end;
  177. error.exit = exit_ok;
  178. error.exit_err = exit_err;
  179. error.exit_status = exit_status;
  180. error.exit_msg = exit_msg;
  181. error.add = add;
  182. error.print = printerr;
  183. error.printadd = printadd;
  184. //Ecriture 1er ligne
  185. fprintf(stderr, "----- Log processus %d (timestamp : %ld) -----\n", getpid(), error.start);
  186. //On indique que l'inialisation a eu lieu
  187. error.init = 1;
  188. }