#include #include #include #include "libcompte.h" static int ecrire_solde(int fd, int cpt_id, int new_solde); pthread_mutex_t mutex_lseek; pthread_mutex_t mutex_transfert; /* Ouvre un fichier compte et retourne le fd a passer aux autres fonctions */ int compte_init(const char* filename) { int fd = open(filename, O_RDWR|O_CREAT, 0600); int ret = pthread_mutex_init(&mutex_lseek, NULL); if(ret < 0){ perror("pthread_mutex_init failed"); return -1; } ret = pthread_mutex_init(&mutex_transfert, NULL); if(ret < 0){ perror("pthread_mutex_init failed"); return -1; } return fd; } /* Ferme un fichier compte */ void compte_finalize(int fd) { close(fd); } /* Cree un nouveau compte */ void creer_compte(int fd, int montant) { int cpt_id = nb_compte(fd); int ret = ecrire_solde(fd, cpt_id, montant); if(ret < 0) { printf("Erreur lors de la création du compte %d\n", cpt_id); return; } } /* Ecrit le solde d'un compte * retourne -1 en cas d'erreur ou 0 sinon */ static int ecrire_solde(int fd, int cpt_id, int new_solde) { int ret = pthread_mutex_lock(&mutex_lseek); if(ret < 0) { perror("pthread_mutex_lock failed"); return -1; } size_t offset = cpt_id * sizeof(int); ret = lseek(fd, offset, SEEK_SET); if(ret <0 && errno == EINVAL) { pthread_mutex_unlock(&mutex_lseek); return -1; } ret = write(fd, &new_solde, sizeof(int)); if(ret != sizeof(int)) { pthread_mutex_unlock(&mutex_lseek); return -1; } ret = pthread_mutex_unlock(&mutex_lseek); if(ret < 0) { perror("pthread_mutex_lock failed"); return -1; } return 0; } /* Lit le solde d'un compte. * retourne -1 en cas d'erreur ou 0 sinon */ int lire_solde(int fd, int cpt_id, int*solde) { int ret = pthread_mutex_lock(&mutex_lseek); if(ret < 0) { perror("pthread_mutex_lock failed"); pthread_mutex_unlock(&mutex_lseek); return -1; } size_t offset = cpt_id * sizeof(int); ret = lseek(fd, offset, SEEK_SET); if(ret < 0) { pthread_mutex_unlock(&mutex_lseek); return -1; } ret = read(fd, solde, sizeof(int)); if(ret != sizeof(int)) { pthread_mutex_unlock(&mutex_lseek); return -1; } ret = pthread_mutex_unlock(&mutex_lseek); if(ret < 0) { perror("pthread_mutex_lock failed"); return -1; } return 0; } /* Retourne le nombre de comptes stockés dans le fichier */ int nb_compte(int fd) { int ret = pthread_mutex_lock(&mutex_lseek); if(ret < 0) { perror("pthread_mutex_lock failed"); pthread_mutex_unlock(&mutex_lseek); return -1; } int offset = lseek(fd, 0, SEEK_END); if(offset < 0) { pthread_mutex_unlock(&mutex_lseek); return -1; } ret = pthread_mutex_unlock(&mutex_lseek); if(ret < 0) { perror("pthread_mutex_lock failed"); return -1; } return offset / sizeof(int); } /* Transfere montant euros du compte cpt_src au compte cpt_dest */ void transfert(int fd, int cpt_src, int cpt_dest, int montant) { int ret = pthread_mutex_lock(&mutex_transfert); if(ret < 0) { perror("pthread_mutex_lock failed"); return; } /* transfere entre deux comptes */ int solde_src, solde_dest; ret = lire_solde(fd, cpt_src, &solde_src); if(ret < 0) { printf("Erreur lors de la lecture du solde %d\n", cpt_src); pthread_mutex_unlock(&mutex_transfert); return; } ret = lire_solde(fd, cpt_dest, &solde_dest); if(ret < 0) { printf("Erreur lors de la lecture du solde %d\n", cpt_dest); pthread_mutex_unlock(&mutex_transfert); return; } solde_src -= montant; solde_dest += montant; ret = ecrire_solde(fd, cpt_src, solde_src); if(ret < 0) { printf("Erreur lors de l'ecriture du solde %d\n", cpt_src); pthread_mutex_unlock(&mutex_transfert); return; } ret = ecrire_solde(fd, cpt_dest, solde_dest); if(ret < 0) { printf("Erreur lors de l'ecriture du solde %d\n", cpt_dest); pthread_mutex_unlock(&mutex_transfert); return; } ret = pthread_mutex_unlock(&mutex_transfert); if(ret < 0) { perror("pthread_mutex_unlock failed"); return; } } /* Calcule la somme de tous les comptes */ int balance(int fd) { int ret = pthread_mutex_lock(&mutex_transfert); if(ret < 0) { perror("pthread_mutex_lock failed"); return -1; } int somme = 0; int ncpt = nb_compte(fd); for(int i=0; i