/* programme de demonstration du probleme liee un acces concurrent */
#include <sys/types.h>
#include <sys/file.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

/* programme d'ajout sans precaution*/
#define ID_PROC		Ajout
#define N_Boucles	10
#define ATTENTE		100
#define NB_INST		5

static int num_inst=0; 

/* fonction de ralentissement
permettant un entrelacement des programmes concurrents*/
void inst_suiv(void) {
int cpte;
for(cpte=0; cpte  < ATTENTE*100000; cpte++);
num_inst = (num_inst<NB_INST)?num_inst+1:1; // affichage du n° d'instruction ds la boucle
printf(" AJOUT instruction %d \n", num_inst);
}

void main (int nbarg, char *tbarg[]) {
int df_n, nombre, num_boucle, nbo_lus, nbo_ecrits;
off_t lret;
  
if ((df_n= open ("NOMBRE",O_RDWR|O_CREAT,0644)) < 0)  {
  perror("ouverture de NOMBRE"); exit(errno);}

// boucle de modification de la valeur de NOMBRE
for (num_boucle=0;num_boucle<N_Boucles;num_boucle++) {
  inst_suiv();
  if ((lret=lseek(df_n,(off_t)0,SEEK_SET)) < 0) {
    perror("1er lseek sur NOMBRE");
    exit(errno);
  }
  inst_suiv();
  if ((nbo_lus=read(df_n,&nombre,sizeof(int))) < sizeof(int) ) {
    perror("lecture NOMBRE");
    exit(errno);
  }
  inst_suiv();
  nombre++;
  inst_suiv();
  if ((lret=lseek(df_n,(off_t)0,SEEK_SET)) < 0)
  { perror("2eme lseek sur NOMBRE"); exit(errno); }
  inst_suiv();
  if ((nbo_ecrits=write(df_n,&nombre,sizeof(int))) < sizeof(int))
  { perror("ecriture NOMBRE"); exit(errno); }
}

// lecture de la valeur finale
if ((lret=lseek(df_n,(off_t)0,SEEK_SET)) < 0)
{ perror("dernier lseek sur NOMBRE"); exit(errno);}

if ((nbo_lus=read(df_n,&nombre,sizeof(int))) < sizeof(int))
{ perror("lecture NOMBRE"); exit(errno); }

printf("Valeur finale (PLUS) nombre: %d \n",nombre);

close(df_n);

}