Ajout d'un système de transactions sécurisées avec gestion des comptes et verrouillage de fichier
This commit is contained in:
parent
9373aa5f6a
commit
0e1da17bee
@ -0,0 +1,179 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ACCOUNT_SIZE 16
|
||||
#define MAX_NAME_LEN 10
|
||||
#define MAX_BALANCE_LEN 5
|
||||
#define FILENAME "../Data/accounts.db"
|
||||
|
||||
// Fonction pour lire un compte dans le fichier avec verrouillage
|
||||
void read_account(int fd, int index, char *name, int *balance) {
|
||||
char buffer[ACCOUNT_SIZE];
|
||||
|
||||
// Placer un verrou exclusif sur la section du fichier correspondant au compte
|
||||
lockf(fd, F_LOCK, ACCOUNT_SIZE);
|
||||
lseek(fd, index * ACCOUNT_SIZE, SEEK_SET);
|
||||
read(fd, buffer, ACCOUNT_SIZE);
|
||||
sscanf(buffer, "%10s %d", name, balance);
|
||||
// Libérer le verrou après lecture
|
||||
lockf(fd, F_ULOCK, ACCOUNT_SIZE);
|
||||
}
|
||||
|
||||
// Fonction pour écrire un compte dans le fichier avec verrouillage
|
||||
void write_account(int fd, int index, const char *name, int balance) {
|
||||
char buffer[ACCOUNT_SIZE];
|
||||
|
||||
// Formater la chaîne avec un nom de 10 caractères et un solde de 5 caractères, espace rempli si nécessaire
|
||||
snprintf(buffer, ACCOUNT_SIZE, "%-10s%5d", name, balance);
|
||||
|
||||
// S'assurer que le buffer est exactement de taille ACCOUNT_SIZE
|
||||
for (int i = strlen(buffer); i < ACCOUNT_SIZE - 1; i++) {
|
||||
buffer[i] = ' ';
|
||||
}
|
||||
buffer[ACCOUNT_SIZE - 1] = '\n'; // Assurez-vous que la ligne est terminée correctement
|
||||
|
||||
// Placer un verrou exclusif sur la section du fichier correspondant au compte
|
||||
lockf(fd, F_LOCK, ACCOUNT_SIZE);
|
||||
lseek(fd, index * ACCOUNT_SIZE, SEEK_SET);
|
||||
write(fd, buffer, ACCOUNT_SIZE);
|
||||
// Libérer le verrou après écriture
|
||||
lockf(fd, F_ULOCK, ACCOUNT_SIZE);
|
||||
}
|
||||
|
||||
// Fonction pour effectuer une transaction avec verrouillage
|
||||
void perform_transaction(int fd, int account_count) {
|
||||
int from_idx = rand() % account_count;
|
||||
int to_idx = rand() % account_count;
|
||||
while (from_idx == to_idx) {
|
||||
to_idx = rand() % account_count;
|
||||
}
|
||||
|
||||
char from_name[MAX_NAME_LEN], to_name[MAX_NAME_LEN];
|
||||
int from_balance, to_balance;
|
||||
|
||||
// Lire les comptes source et destination
|
||||
read_account(fd, from_idx, from_name, &from_balance);
|
||||
read_account(fd, to_idx, to_name, &to_balance);
|
||||
|
||||
// Calculer un montant aléatoire à transférer (max 20% du solde source)
|
||||
int max_transfer = from_balance / 5;
|
||||
if (max_transfer > 0) {
|
||||
int transfer_amount = rand() % max_transfer;
|
||||
|
||||
// Effectuer la transaction
|
||||
from_balance -= transfer_amount;
|
||||
to_balance += transfer_amount;
|
||||
|
||||
// Écrire les nouveaux soldes dans le fichier
|
||||
write_account(fd, from_idx, from_name, from_balance);
|
||||
write_account(fd, to_idx, to_name, to_balance);
|
||||
|
||||
printf("Transaction : %s -> %s : %d€\n", from_name, to_name, transfer_amount);
|
||||
} else {
|
||||
printf("Transaction annulée : Fonds insufisants %s\n", from_name);
|
||||
}
|
||||
}
|
||||
|
||||
// Fonction pour un processus de transactions
|
||||
void process_transactions(int transactions, int account_count) {
|
||||
int fd = open(FILENAME, O_RDWR);
|
||||
if (fd < 0) {
|
||||
perror("Erreur : Impossible d'ouvrir le fichier");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < transactions; i++) {
|
||||
perform_transaction(fd, account_count);
|
||||
//usleep(rand() % 100000); // Temporisation aléatoire
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
int calculate_total_balance() {
|
||||
int fd = open(FILENAME, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror("Erreur : Impossible d'ouvrir le fichier");
|
||||
return -1;
|
||||
}
|
||||
|
||||
off_t file_size = lseek(fd, 0, SEEK_END);
|
||||
int account_count = file_size / ACCOUNT_SIZE;
|
||||
|
||||
int total_balance = 0;
|
||||
char name[MAX_NAME_LEN];
|
||||
int balance;
|
||||
|
||||
for (int i = 0; i < account_count; i++) {
|
||||
read_account(fd, i, name, &balance);
|
||||
total_balance += balance;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return total_balance;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s <number_of_processes> <transactions_per_process>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int num_processes = atoi(argv[1]);
|
||||
int transactions_per_process = atoi(argv[2]);
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
// Calcul du solde total initial
|
||||
int initial_balance = calculate_total_balance();
|
||||
if (initial_balance < 0) {
|
||||
return 1; // Erreur lors de l'ouverture du fichier
|
||||
}
|
||||
printf("Solde total initial : %d€\n", initial_balance);
|
||||
|
||||
// Ouvrir le fichier pour déterminer le nombre de comptes
|
||||
int fd = open(FILENAME, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror("Erreur : Impossible d'ouvrir le fichier");
|
||||
return 1;
|
||||
}
|
||||
off_t file_size = lseek(fd, 0, SEEK_END);
|
||||
close(fd);
|
||||
|
||||
int account_count = file_size / ACCOUNT_SIZE;
|
||||
|
||||
printf("Nombre de comptes : %d\n", account_count);
|
||||
|
||||
// Créer les processus enfants
|
||||
for (int i = 0; i < num_processes; i++) {
|
||||
if (fork() == 0) {
|
||||
process_transactions(transactions_per_process, account_count);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Attendre les processus enfants
|
||||
for (int i = 0; i < num_processes; i++) {
|
||||
wait(NULL);
|
||||
}
|
||||
|
||||
// Calcul du solde total final
|
||||
int final_balance = calculate_total_balance();
|
||||
if (final_balance < 0) {
|
||||
return 1; // Erreur lors de l'ouverture du fichier
|
||||
}
|
||||
printf("Solde total final : %d€\n", final_balance);
|
||||
|
||||
if (initial_balance != final_balance) {
|
||||
printf("Le solde final est différent du solde initial...\n");
|
||||
}
|
||||
|
||||
printf("Tout les processus sont terminés !\n");
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user