compteur-arg.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include <stdio.h>
  2. #include <signal.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdbool.h> // bool
  6. #include <unistd.h> //sleep
  7. /*
  8. - compteur avec arg nb de minutes / affichage toutes les 10S
  9. usage : ./compte 4 ( pour 4 minute)
  10. - capture du signal SIGUSR2 12 pour checkpoint: kill -s 12 LE_PID pour tester
  11. - le checkpoint consiste à sauvegarder le compteur dans le fichier context_compteur_$ARG.txt
  12. - relancer le programme avec le même $ARG reprend à partir de context_compteur_$ARG.txt la valeur contenu dans
  13. - lorsque décompte est fini alors que le fichier context_compteur_$ARG.txt existe,
  14. ce dernier est déplacé en done.context_compteur_$ARG.txt
  15. - si ce dernier n'existait pas, le fichier done.context_compteur_$ARG.txt est tout de même crée
  16. */
  17. #define SIZE 1
  18. #define NUMELEM 5
  19. #define SIGNAL_CHECKPOINT SIGUSR2
  20. /*compteur variable globale ( main et signal ) */
  21. int compteur;
  22. bool checkpt;
  23. //findice_ckpt
  24. FILE * fp;
  25. // nom fichier sauvegarde contexte
  26. char nomFich[256];
  27. char doneFich[256];
  28. // fonction capture du signal
  29. void sig_handler(int signal)
  30. {
  31. printf("signal checkpoint recu \n");
  32. checkpt=true;
  33. }
  34. int main( int argc, char *argv[] )
  35. {
  36. //int i ;
  37. if(argc<=1) {
  38. printf("merci de passer le nombre de minutes en argument, arret du programme...\n");
  39. exit(1);
  40. } // sinon, on continue:
  41. checkpt=false;
  42. signal(SIGNAL_CHECKPOINT, sig_handler);
  43. // nom du fichier de contexte (déjà existant ou à créér) en cas de checkpoint
  44. snprintf(nomFich, sizeof nomFich, "context_compteur_%s.txt", argv[1]);
  45. fp = fopen( nomFich, "rb");
  46. /* avant de lancer le compteur on vérifie s'il n'y a pas un checkpoint
  47. (existance du fichier) context_compteur_$PARAMETRE.txt
  48. si oui, initialisation de compteur à sa valeur du dernier checpoint*/
  49. if (fp){
  50. fread( &compteur , sizeof(int) , 1 , fp);
  51. printf("valeur compteur au precedent checkpoint = %d s\n", compteur*10);
  52. fclose(fp);
  53. }else{
  54. compteur=0;
  55. }
  56. // ---- le Compteur proprement dit ---------
  57. //( approximatif ce n'est pas un chrono!)
  58. int max= atoi(argv[1])*6 ; /* max exprimé en minute (environ: ce n'est pas un chrono!)*/
  59. printf("--- compteur de %d minutes ----\n",max/6);
  60. // while ((compteur < max) && ( checkpt==false ))
  61. while ((compteur < max + 1) && ( !checkpt ))
  62. {
  63. printf("compteur = %03d0s\n", compteur);
  64. // force l'écriture sur la sortie
  65. fflush(stdout);
  66. sleep(10);
  67. compteur++;
  68. }
  69. // checkpoint:
  70. // si la boucle a été interrompue par réception du signal(kill -s 12 le_PID)
  71. if(checkpt){
  72. printf("valeur du compteur enregistre: %d\n", compteur*10);
  73. //fp = fopen("context_compteur.txt", "wb");
  74. fp = fopen(nomFich, "wb");
  75. if(fp == NULL) {
  76. printf("error creating file");
  77. }
  78. else {
  79. fwrite( &compteur , sizeof(int) , 1 , fp);
  80. fclose(fp);
  81. }
  82. }
  83. // checkpoint tjrs négatif
  84. else {
  85. // on est est arrivé au bout, s'il y a un fichier de checkpoint
  86. // on le supprime( ou le déplace)
  87. snprintf(doneFich, sizeof nomFich, "done.%s", nomFich);
  88. if (fp){
  89. rename(nomFich, doneFich);
  90. // ou bien:
  91. //remove(nomFich);
  92. }
  93. // facultatif: on crée le fichier done.context_compteur_$LePARAM.txt
  94. // (facilite post traitement oar)
  95. else{
  96. fp = fopen(doneFich,"w");
  97. fclose(fp);
  98. }
  99. }
  100. return 0;
  101. }