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>