Annotation of rpl/src/gestion_fichiers.c, revision 1.4

1.1       bertrand    1: /*
                      2: ================================================================================
1.3       bertrand    3:   RPL/2 (R) version 4.0.11
1.1       bertrand    4:   Copyright (C) 1989-2010 Dr. BERTRAND Joël
                      5: 
                      6:   This file is part of RPL/2.
                      7: 
                      8:   RPL/2 is free software; you can redistribute it and/or modify it
                      9:   under the terms of the CeCILL V2 License as published by the french
                     10:   CEA, CNRS and INRIA.
                     11:  
                     12:   RPL/2 is distributed in the hope that it will be useful, but WITHOUT
                     13:   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
                     14:   FITNESS FOR A PARTICULAR PURPOSE.  See the CeCILL V2 License
                     15:   for more details.
                     16:  
                     17:   You should have received a copy of the CeCILL License
                     18:   along with RPL/2. If not, write to info@cecill.info.
                     19: ================================================================================
                     20: */
                     21: 
                     22: 
                     23: #include "rpl.conv.h"
                     24: 
                     25: 
                     26: /*
                     27: ================================================================================
                     28:   Routines de gestion des fichiers
                     29: ================================================================================
                     30:   Entrées : nom du fichier
                     31: --------------------------------------------------------------------------------
                     32:   Sorties : 0, le fichier n'existe pas, -1, il existe.
                     33: --------------------------------------------------------------------------------
                     34:   Effets de bord : néant
                     35: ================================================================================
                     36: */
                     37: 
                     38: /*
                     39:  * Génère un nom de fichier
                     40:  */
                     41: 
                     42: unsigned char *
                     43: creation_nom_fichier(struct_processus *s_etat_processus,
                     44:        unsigned char *chemin)
                     45: {
                     46:    /*
                     47:     * Le nom du fichier est créé à l'aide du pid du processus et
                     48:     * d'un numéro d'ordre pour ce processus.
                     49:     */
                     50: 
                     51:    logical1                        erreur;
                     52: 
                     53:    logical1                        existence;
                     54:    logical1                        ouverture;
                     55: 
                     56:    pthread_mutex_t                 exclusion = PTHREAD_MUTEX_INITIALIZER;
                     57: 
                     58:    unsigned char                   *nom;
                     59:    unsigned char                   tampon[256 + 1];
                     60: 
                     61:    unsigned long                   ordre_initial;
                     62:    unsigned long                   unite;
                     63: 
                     64:    static unsigned long            ordre = 0;
                     65: 
                     66:    if (pthread_mutex_lock(&exclusion) != 0)
                     67:    {
                     68:        return(NULL);
                     69:    }
                     70: 
                     71:    ordre_initial = ordre;
                     72: 
                     73:    if (pthread_mutex_unlock(&exclusion) != 0)
                     74:    {
                     75:        return(NULL);
                     76:    }
                     77: 
                     78:    do
                     79:    {
                     80:        sprintf(tampon, "RPL2-%lu-%lu-%lu", (unsigned long) getpid(),
                     81:                (unsigned long) pthread_self(), ordre);
                     82: 
                     83:        if (chemin == NULL)
                     84:        {
                     85:            if ((nom = malloc((strlen(tampon) + 1) *
                     86:                    sizeof(unsigned char))) == NULL)
                     87:            {
                     88:                return(NULL);
                     89:            }
                     90: 
                     91:            strcpy(nom, tampon);
                     92:        }
                     93:        else
                     94:        {
                     95:            if ((nom = malloc((strlen(chemin) + strlen(tampon) + 2) *
                     96:                    sizeof(unsigned char))) == NULL)
                     97:            {
                     98:                return(NULL);
                     99:            }
                    100: 
                    101:            sprintf(nom, "%s/%s", chemin, tampon);
                    102:        }
                    103: 
                    104:        if (pthread_mutex_lock(&exclusion) != 0)
                    105:        {
                    106:            return(NULL);
                    107:        }
                    108: 
                    109:        ordre++;
                    110: 
                    111:        if (pthread_mutex_unlock(&exclusion) != 0)
                    112:        {
                    113:            return(NULL);
                    114:        }
                    115: 
                    116:        if (ordre == ordre_initial)
                    117:        {
                    118:            // Il n'existe plus aucun nom de fichier disponible...
                    119: 
                    120:            free(nom);
                    121:            return(NULL);
                    122:        }
                    123: 
                    124:        erreur = caracteristiques_fichier(s_etat_processus,
                    125:                nom, &existence, &ouverture, &unite);
                    126: 
                    127:        if (erreur != 0)
                    128:        {
                    129:            free(nom);
                    130:            return(NULL);
                    131:        }
                    132: 
                    133:        if (existence == d_vrai)
                    134:        {
                    135:            free(nom);
                    136:        }
                    137:    } while(existence == d_vrai);
                    138: 
                    139:    return(nom);
                    140: }
                    141: 
                    142: /*
                    143:  * Efface un fichier
                    144:  */
                    145: 
                    146: logical1
                    147: destruction_fichier(unsigned char *nom_fichier)
                    148: {
                    149:    return((unlink(nom_fichier) == 0) ? d_absence_erreur : d_erreur);
                    150: }
                    151: 
                    152: /*
                    153:  * Renvoie le descripteur en fonction de la structure de contrôle du fichier
                    154:  */
                    155: 
                    156: file *
                    157: descripteur_fichier(struct_processus *s_etat_processus,
                    158:        struct_fichier *s_fichier)
                    159: {
                    160:    logical1                    concordance_descripteurs;
                    161: 
                    162:    struct_liste_chainee        *l_element_courant;
                    163: 
                    164:    l_element_courant = (*s_etat_processus).s_fichiers;
                    165:    concordance_descripteurs = d_faux;
                    166: 
                    167:    while(l_element_courant != NULL)
                    168:    {
                    169:        if ((*((struct_descripteur_fichier *) (*l_element_courant).donnee))
                    170:                .identifiant == (*s_fichier).descripteur)
                    171:        {
                    172:            if (((*((struct_descripteur_fichier *) (*l_element_courant).donnee))
                    173:                    .pid == (*s_fichier).pid) && (pthread_equal(
                    174:                    (*((struct_descripteur_fichier *) (*l_element_courant)
                    175:                    .donnee)).tid, pthread_self()) != 0))
                    176:            {
                    177:                return((*((struct_descripteur_fichier *)
                    178:                        (*l_element_courant).donnee)).descripteur);
                    179:            }
                    180:            else
                    181:            {
                    182:                concordance_descripteurs = d_vrai;
                    183:            }
                    184:        }
                    185: 
                    186:        l_element_courant = (*l_element_courant).suivant;
                    187:    }
                    188: 
                    189:    if (concordance_descripteurs == d_vrai)
                    190:    {
                    191:        (*s_etat_processus).erreur_execution = d_ex_fichier_hors_contexte;
                    192:    }
                    193:    else
                    194:    {
                    195:        (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
                    196:    }
                    197: 
                    198:    return(NULL);
                    199: }
                    200: 
                    201: /*
                    202:  * Recherche un chemin pour les fichiers temporaires
                    203:  */
                    204: 
                    205: unsigned char *
                    206: recherche_chemin_fichiers_temporaires(struct_processus *s_etat_processus)
                    207: {
                    208:    file                *fichier;
                    209: 
                    210:    unsigned char       *candidat;
                    211:    unsigned char       *chemin;
                    212:    unsigned char       *chemins[] = { "$RPL_TMP_PATH",
                    213:                                "/tmp", "/var/tmp", NULL };
                    214:    unsigned char       *nom_candidat;
                    215: 
                    216:    unsigned long int   i;
                    217: 
                    218:    i = 0;
                    219:    chemin = NULL;
                    220: 
                    221:    while(chemin == NULL)
                    222:    {
                    223:        if (chemins[i][0] == '$')
                    224:        {
                    225:            candidat = getenv("RPL_TMP_PATH");
                    226: 
                    227:            if (candidat != NULL)
                    228:            {
                    229:                if ((nom_candidat = creation_nom_fichier(s_etat_processus,
                    230:                        candidat)) == NULL)
                    231:                {
                    232:                    return NULL;
                    233:                }
                    234: 
                    235:                if ((fichier = fopen(nom_candidat, "w+")) != NULL)
                    236:                {
                    237:                    fclose(fichier);
                    238:                    unlink(nom_candidat);
                    239:                    free(nom_candidat);
                    240: 
                    241:                    if ((chemin = malloc((strlen(candidat) + 1)
                    242:                            * sizeof(unsigned char))) != NULL)
                    243:                    {
                    244:                        strcpy(chemin, candidat);
                    245:                    }
                    246:                    else
                    247:                    {
                    248:                        return NULL;
                    249:                    }
                    250:                }
                    251:                else
                    252:                {
                    253:                    free(nom_candidat);
                    254:                }
                    255:            }
                    256:        }
                    257:        else
                    258:        {
                    259:            if ((nom_candidat = creation_nom_fichier(s_etat_processus,
                    260:                    chemins[i])) == NULL)
                    261:            {
                    262:                return NULL;
                    263:            }
                    264: 
                    265:            if ((fichier = fopen(nom_candidat, "w+")) != NULL)
                    266:            {
                    267:                fclose(fichier);
                    268:                unlink(nom_candidat);
                    269:                free(nom_candidat);
                    270: 
                    271:                if ((chemin = malloc((strlen(chemins[i]) + 1)
                    272:                        * sizeof(unsigned char))) != NULL)
                    273:                {
                    274:                    strcpy(chemin, chemins[i]);
                    275:                }
                    276:                else
                    277:                {
                    278:                    return NULL;
                    279:                }
                    280:            }
                    281:            else
                    282:            {
                    283:                free(nom_candidat);
                    284:            }
                    285:        }
                    286: 
                    287:        i++;
                    288:    }
                    289: 
                    290:    return chemin;
                    291: }
                    292: 
                    293: 
                    294: /*
                    295: ================================================================================
                    296:   Fonction d'interrogation du fichier
                    297: ================================================================================
                    298: */
                    299: 
                    300: logical1
                    301: caracteristiques_fichier(struct_processus *s_etat_processus,
                    302:        unsigned char *nom, logical1 *existence, logical1 *ouverture,
                    303:        unsigned long *unite)
                    304: {
                    305:    int                             descripteur;
                    306: 
                    307:    logical1                        erreur;
                    308: 
                    309:    struct_liste_chainee            *l_element_courant;
                    310: 
                    311:    (*unite) = 0;
                    312:    (*ouverture) = d_faux;
                    313:    (*existence) = d_faux;
                    314: 
1.4     ! bertrand  315:    if ((descripteur = open(nom, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) == -1)
1.1       bertrand  316:    {
                    317:        if (errno == EEXIST)
                    318:        {
                    319:            // Le fichier préexiste.
                    320: 
                    321:            erreur = d_absence_erreur;
                    322:            (*existence) = d_vrai;
                    323: 
                    324:            // On chercher à savoir si le fichier est ouvert. S'il est ouvert,
                    325:            // on renvoie son unité de rattachement.
                    326: 
                    327:            l_element_courant = (*s_etat_processus).s_fichiers;
                    328: 
                    329:            while(l_element_courant != NULL)
                    330:            {
                    331:                if (strcmp((*((struct_descripteur_fichier *)
                    332:                        (*l_element_courant).donnee)).nom, nom) == 0)
                    333:                {
                    334:                    if (((*((struct_descripteur_fichier *) (*l_element_courant)
                    335:                            .donnee)).pid == getpid()) &&
                    336:                            (pthread_equal((*((struct_descripteur_fichier *)
                    337:                            (*l_element_courant).donnee)).tid, pthread_self())
                    338:                            != 0))
                    339:                    {
                    340:                        (*ouverture) = d_vrai;
                    341:                        (*unite) = (unsigned long)
                    342:                                fileno((*((struct_descripteur_fichier *)
                    343:                                (*l_element_courant).donnee)).descripteur);
                    344:                        break;
                    345:                    }
                    346:                }
                    347: 
                    348:                l_element_courant = (*l_element_courant).suivant;
                    349:            }
                    350:        }
                    351:        else
                    352:        {
                    353:            erreur = d_erreur;
                    354:        }
                    355:    }
                    356:    else
                    357:    {
                    358:        close(descripteur);
                    359:        unlink(nom);
                    360:        erreur = d_absence_erreur;
                    361:    }
                    362: 
                    363:    return(erreur);
                    364: }
                    365: 
                    366: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>