--- rpl/src/gestion_fichiers.c 2010/01/26 15:22:44 1.1.1.1 +++ rpl/src/gestion_fichiers.c 2022/09/07 13:40:31 1.79 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.0.9 - Copyright (C) 1989-2010 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.34 + Copyright (C) 1989-2021 Dr. BERTRAND Joël This file is part of RPL/2. @@ -20,7 +20,7 @@ */ -#include "rpl.conv.h" +#include "rpl-conv.h" /* @@ -77,8 +77,8 @@ creation_nom_fichier(struct_processus *s do { - sprintf(tampon, "RPL2-%lu-%lu-%lu", (unsigned long) getpid(), - (unsigned long) pthread_self(), ordre); + sprintf(tampon, "RPL-%llu-%llu-%lu", (unsigned long long) getpid(), + (unsigned long long) pthread_self(), ordre); if (chemin == NULL) { @@ -153,7 +153,7 @@ destruction_fichier(unsigned char *nom_f * Renvoie le descripteur en fonction de la structure de contrôle du fichier */ -file * +struct_descripteur_fichier * descripteur_fichier(struct_processus *s_etat_processus, struct_fichier *s_fichier) { @@ -174,8 +174,8 @@ descripteur_fichier(struct_processus *s_ (*((struct_descripteur_fichier *) (*l_element_courant) .donnee)).tid, pthread_self()) != 0)) { - return((*((struct_descripteur_fichier *) - (*l_element_courant).donnee)).descripteur); + return((struct_descripteur_fichier *) + (*l_element_courant).donnee); } else { @@ -222,14 +222,14 @@ recherche_chemin_fichiers_temporaires(st { if (chemins[i][0] == '$') { - candidat = getenv("RPL_TMP_PATH"); + candidat = getenv(chemins[i] + 1); if (candidat != NULL) { if ((nom_candidat = creation_nom_fichier(s_etat_processus, candidat)) == NULL) { - return NULL; + return(NULL); } if ((fichier = fopen(nom_candidat, "w+")) != NULL) @@ -245,7 +245,7 @@ recherche_chemin_fichiers_temporaires(st } else { - return NULL; + return(NULL); } } else @@ -259,7 +259,7 @@ recherche_chemin_fichiers_temporaires(st if ((nom_candidat = creation_nom_fichier(s_etat_processus, chemins[i])) == NULL) { - return NULL; + return(NULL); } if ((fichier = fopen(nom_candidat, "w+")) != NULL) @@ -275,7 +275,7 @@ recherche_chemin_fichiers_temporaires(st } else { - return NULL; + return(NULL); } } else @@ -287,15 +287,13 @@ recherche_chemin_fichiers_temporaires(st i++; } - return chemin; + return(chemin); } /* -================================================================================ - Fonction d'interrogation du fichier -================================================================================ -*/ + * Fonction d'interrogation du fichier + */ logical1 caracteristiques_fichier(struct_processus *s_etat_processus, @@ -312,7 +310,7 @@ caracteristiques_fichier(struct_processu (*ouverture) = d_faux; (*existence) = d_faux; - if ((descripteur = open(nom, O_CREAT | O_EXCL)) == -1) + if ((descripteur = open(nom, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) == -1) { if (errno == EEXIST) { @@ -338,9 +336,11 @@ caracteristiques_fichier(struct_processu != 0)) { (*ouverture) = d_vrai; + (*unite) = (unsigned long) fileno((*((struct_descripteur_fichier *) - (*l_element_courant).donnee)).descripteur); + (*l_element_courant).donnee)) + .descripteur_c); break; } } @@ -348,6 +348,53 @@ caracteristiques_fichier(struct_processu l_element_courant = (*l_element_courant).suivant; } } + else if (errno == EACCES) + { + // Le répertoire n'est pas accessible en écriture. On tente + // l'ouverture du fichier. + + if ((descripteur = open(nom, O_RDONLY, S_IRUSR | S_IWUSR)) == -1) + { + // Le fichier n'existe pas. + close(descripteur); + erreur = d_absence_erreur; + } + else + { + erreur = d_absence_erreur; + (*existence) = d_vrai; + + // On chercher à savoir si le fichier est ouvert. + // S'il est ouvert, on renvoie son unité de rattachement. + + l_element_courant = (*s_etat_processus).s_fichiers; + + while(l_element_courant != NULL) + { + if (strcmp((*((struct_descripteur_fichier *) + (*l_element_courant).donnee)).nom, nom) == 0) + { + if (((*((struct_descripteur_fichier *) + (*l_element_courant).donnee)).pid == getpid()) + && (pthread_equal( + (*((struct_descripteur_fichier *) + (*l_element_courant).donnee)).tid, + pthread_self()) != 0)) + { + (*ouverture) = d_vrai; + + (*unite) = (unsigned long) + fileno((*((struct_descripteur_fichier *) + (*l_element_courant).donnee)) + .descripteur_c); + break; + } + } + + l_element_courant = (*l_element_courant).suivant; + } + } + } else { erreur = d_erreur; @@ -363,4 +410,335 @@ caracteristiques_fichier(struct_processu return(erreur); } + +/* +================================================================================ + Routines d'initialisation des fichiers à accès direct et indexé +================================================================================ + Entrées : pointeur sur le fichier SQLITE +-------------------------------------------------------------------------------- + Sorties : drapeau d'erreur +-------------------------------------------------------------------------------- + Effets de bord : néant +================================================================================ +*/ + +/* + * Un fichier à accès direct se compose d'une seule table : + * 1: identifiant (entier sur 64 bits) -> enregistrement + * + * Un fichier à accès indexé comporte trois tables : + * 1 : contrôle + * 2 : clef (unique) -> identifiant (entier sur 64 bits) + * 3 : identifiant -> collection d'enregistrements + * + * La table de contrôle contient + * 1/ la position de la clef pour les fichiers à accès indexés + */ + +static logical1 +initialisation_controle(struct_processus *s_etat_processus, sqlite3 *sqlite, + integer8 position_clef, logical1 fichier_indexe) +{ + const char commande1[] = + "create table control(id integer primary key asc, key integer)"; + const char commande2[] = + "insert into control (id, key) values (1, %lld)"; + const char *queue; + + sqlite3_stmt *ppStmt; + + unsigned char *commande; + + if (sqlite3_prepare_v2(sqlite, commande1, (int) strlen(commande1), &ppStmt, + &queue) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_step(ppStmt) != SQLITE_DONE) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_finalize(ppStmt) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (fichier_indexe == d_vrai) + { + if (alsprintf(s_etat_processus, &commande, commande2, position_clef) + < 0) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(d_erreur); + } + + if (sqlite3_prepare_v2(sqlite, commande, (int) strlen(commande), + &ppStmt, &queue) != SQLITE_OK) + { + free(commande); + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_step(ppStmt) != SQLITE_DONE) + { + free(commande); + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_finalize(ppStmt) != SQLITE_OK) + { + free(commande); + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + free(commande); + } + + return(d_absence_erreur); +} + +logical1 +initialisation_fichier_acces_indexe(struct_processus *s_etat_processus, + sqlite3 *sqlite, integer8 position_clef, logical1 binaire) +{ + const char commande1[] = + "create table data(id integer primary key asc, key_id integer, " + "data text, sequence integer)"; + const char commande10[] = + "create table key(id integer primary key asc, key text)"; + const char commande2[] = + "create table data(id integer primary key asc, key_id integer, " + "data blob, sequence integer)"; + const char commande20[] = + "create table key(id integer primary key asc, key blob)"; + const char commande3[] = + "create index data_idx on data(key_id)"; + const char commande4[] = + "create index key_idx on key(key)"; + const char *queue; + + sqlite3_stmt *ppStmt; + + if (initialisation_controle(s_etat_processus, sqlite, position_clef, d_vrai) + != d_absence_erreur) + { + return(d_erreur); + } + + if (binaire == d_faux) + { + if (sqlite3_prepare_v2(sqlite, commande1, (int) strlen(commande1), + &ppStmt, &queue) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_step(ppStmt) != SQLITE_DONE) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_finalize(ppStmt) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_prepare_v2(sqlite, commande10, (int) strlen(commande10), + &ppStmt, &queue) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_step(ppStmt) != SQLITE_DONE) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_finalize(ppStmt) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + } + else + { + if (sqlite3_prepare_v2(sqlite, commande2, (int) strlen(commande2), + &ppStmt, &queue) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_step(ppStmt) != SQLITE_DONE) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_finalize(ppStmt) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_prepare_v2(sqlite, commande20, (int) strlen(commande20), + &ppStmt, &queue) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_step(ppStmt) != SQLITE_DONE) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_finalize(ppStmt) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + } + + if (sqlite3_prepare_v2(sqlite, commande3, (int) strlen(commande3), &ppStmt, + &queue) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_step(ppStmt) != SQLITE_DONE) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_finalize(ppStmt) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_prepare_v2(sqlite, commande4, (int) strlen(commande4), &ppStmt, + &queue) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_step(ppStmt) != SQLITE_DONE) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_finalize(ppStmt) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + return(d_absence_erreur); +} + +logical1 +initialisation_fichier_acces_direct(struct_processus *s_etat_processus, + sqlite3 *sqlite, logical1 binaire) +{ + const char commande1[] = + "create table data(id integer primary key asc, data text)"; + const char commande2[] = + "create table data(id integer primary key asc, data blob)"; + const char commande3[] = + "create index data_idx on data(id)"; + const char *queue; + + sqlite3_stmt *ppStmt; + + if (initialisation_controle(s_etat_processus, sqlite, (integer8) 0, d_faux) + != d_absence_erreur) + { + return(d_erreur); + } + + if (binaire == d_faux) + { + if (sqlite3_prepare_v2(sqlite, commande1, (int) strlen(commande1), + &ppStmt, &queue) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_step(ppStmt) != SQLITE_DONE) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_finalize(ppStmt) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + } + else + { + if (sqlite3_prepare_v2(sqlite, commande2, (int) strlen(commande2), + &ppStmt, &queue) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_step(ppStmt) != SQLITE_DONE) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_finalize(ppStmt) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + } + + if (sqlite3_prepare_v2(sqlite, commande3, (int) strlen(commande3), &ppStmt, + &queue) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_step(ppStmt) != SQLITE_DONE) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + if (sqlite3_finalize(ppStmt) != SQLITE_OK) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return(d_erreur); + } + + return(d_absence_erreur); +} + // vim: ts=4