123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- #include <stdio.h>
- #include <signal.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdbool.h> // bool
- #include <unistd.h> //sleep
- /*
- - compteur avec arg nb de minutes / affichage toutes les 10S
- usage : ./compte 4 ( pour 4 minute)
- - capture du signal SIGUSR2 12 pour checkpoint: kill -s 12 LE_PID pour tester
- - le checkpoint consiste à sauvegarder le compteur dans le fichier context_compteur_$ARG.txt
- - relancer le programme avec le même $ARG reprend à partir de context_compteur_$ARG.txt la valeur contenu dans
- - lorsque décompte est fini alors que le fichier context_compteur_$ARG.txt existe,
- ce dernier est déplacé en done.context_compteur_$ARG.txt
- - si ce dernier n'existait pas, le fichier done.context_compteur_$ARG.txt est tout de même crée
- */
- #define SIZE 1
- #define NUMELEM 5
- #define SIGNAL_CHECKPOINT SIGUSR2
- /*compteur variable globale ( main et signal ) */
- int compteur;
- bool checkpt;
- //findice_ckpt
- FILE * fp;
- // nom fichier sauvegarde contexte
- char nomFich[256];
- char doneFich[256];
- // fonction capture du signal
- void sig_handler(int signal)
- {
- printf("signal checkpoint recu \n");
- checkpt=true;
- }
- int main( int argc, char *argv[] )
- {
- //int i ;
- if(argc<=1) {
- printf("merci de passer le nombre de minutes en argument, arret du programme...\n");
- exit(1);
- } // sinon, on continue:
- checkpt=false;
- signal(SIGNAL_CHECKPOINT, sig_handler);
-
- // nom du fichier de contexte (déjà existant ou à créér) en cas de checkpoint
-
- snprintf(nomFich, sizeof nomFich, "context_compteur_%s.txt", argv[1]);
- fp = fopen( nomFich, "rb");
- /* avant de lancer le compteur on vérifie s'il n'y a pas un checkpoint
- (existance du fichier) context_compteur_$PARAMETRE.txt
- si oui, initialisation de compteur à sa valeur du dernier checpoint*/
-
- if (fp){
- fread( &compteur , sizeof(int) , 1 , fp);
- printf("valeur compteur au precedent checkpoint = %d s\n", compteur*10);
- fclose(fp);
- }else{
- compteur=0;
- }
- // ---- le Compteur proprement dit ---------
- //( approximatif ce n'est pas un chrono!)
- int max= atoi(argv[1])*6 ; /* max exprimé en minute (environ: ce n'est pas un chrono!)*/
- printf("--- compteur de %d minutes ----\n",max/6);
-
- // while ((compteur < max) && ( checkpt==false ))
- while ((compteur < max + 1) && ( !checkpt ))
- {
- printf("compteur = %03d0s\n", compteur);
- // force l'écriture sur la sortie
- fflush(stdout);
- sleep(10);
- compteur++;
- }
- // checkpoint:
- // si la boucle a été interrompue par réception du signal(kill -s 12 le_PID)
- if(checkpt){
- printf("valeur du compteur enregistre: %d\n", compteur*10);
- //fp = fopen("context_compteur.txt", "wb");
- fp = fopen(nomFich, "wb");
- if(fp == NULL) {
- printf("error creating file");
- }
- else {
- fwrite( &compteur , sizeof(int) , 1 , fp);
- fclose(fp);
- }
- }
- // checkpoint tjrs négatif
- else {
- // on est est arrivé au bout, s'il y a un fichier de checkpoint
- // on le supprime( ou le déplace)
- snprintf(doneFich, sizeof nomFich, "done.%s", nomFich);
- if (fp){
- rename(nomFich, doneFich);
- // ou bien:
- //remove(nomFich);
- }
- // facultatif: on crée le fichier done.context_compteur_$LePARAM.txt
- // (facilite post traitement oar)
- else{
- fp = fopen(doneFich,"w");
- fclose(fp);
- }
- }
- return 0;
- }
|