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

1.1     ! bertrand    1: /*
        !             2: ================================================================================
        !             3:   RPL/2 (R) version 4.0.9
        !             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: 
        !           315:    if ((descripteur = open(nom, O_CREAT | O_EXCL)) == -1)
        !           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>