/* Programme pour afficher "instantanement" la i-ème ligne d'un fichier en * s'appuyant sur son fichier d'index cree avec gli.c * Syntaxe : * gl nomFichier numLigne * * Résultat : * Affichage de la ligne numéro numLigne de nomFichier */ #include #include #include #include char ligne[1025]; /* On suppose que les lignes font au plus 1024 caractères (1025-sizeof('\0') */ void enfant(char *nameSource, int numLigne, int filedesWrite){ FILE *source; FILE *idx; char nameIdx[1024]; int offset[2]; /* Ouverture source */ source = fopen(nameSource, "r"); if (source == NULL){ perror("fopen source"); exit(1); } /* Ouverture idx */ strcat(strcpy(nameIdx,nameSource), ".idx"); idx = fopen(nameIdx, "r"); if (idx == NULL){ perror("fopen idx"); exit(1); } /* Lecture du fichier d'index : offset est un tableau pour qu'on lise * en une fois l'offset de la ligne numLigne et l'offset de la ligne * numLigne+1 */ if (fseek(idx, numLigne*sizeof(int), SEEK_SET) < 0){ perror("fseek idx"); exit(1); } if (fread(offset, sizeof(int), 2, idx) != 2) { printf("Ligne %d n'existe pas !\n", numLigne); exit(1); } /* Lecture de la i-ème ligne du fichier */ if (fseek(source, offset[0]*sizeof(char), SEEK_SET) < 0){ perror("fseek source"); exit(1); } if (fread(ligne, sizeof(char), offset[1]-offset[0], source) != offset[1]-offset[0]) { perror("fread source"); exit(1); } /* On met un '\0' à la fin de ligne, sinon ça fait désordre... */ ligne[offset[1]-offset[0]] = '\0'; /* On écrit le résulat dans le pipe */ write(filedesWrite, ligne, sizeof(ligne)); /* Libération ressources specifiques enfant */ if (fclose(source) < 0){ perror("fclose source"); exit(1); } if (fclose(idx) < 0){ perror("fclose idx"); exit(1); } } void parent(int filedesRead, int numLigne){ /* Lecture du tube */ read(filedesRead, ligne, sizeof(ligne)); /* Affichage du résultat */ printf("Ligne %d = \"%s\"\n", numLigne, ligne); } int main(int argc, char *argv[]) { int filedes[2]; if (argc != 3) { fputs("USAGE = gl nomFichier numLigne\n", stderr); exit(1); } /* Ouverture du pipe */ if (pipe(filedes) < 0){ perror("pipe"); exit(1); } /* On forke */ switch(fork()){ case -1: perror("fork"); exit(1); case 0: enfant(argv[1], atoi(argv[2]), filedes[1]); break; default: parent(filedes[0], atoi(argv[2])); break; } /* Libération ressources communes */ if (close(filedes[0]) < 0){ perror("fclose 0"); exit(1); } if (close(filedes[1]) < 0){ perror("fclose 1"); exit(1); } return 0; }