error.c 3.8 KB

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