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. "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(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. }