lire un fichier qui n’existe pas

J’ai un petit programme qui imprime le contenu des fichiers en utilisant l’appel système – read.

unsigned char buffer[8]; size_t offset=0; size_t bytes_read; int i; int fd = open(argv[1], O_RDONLY); do{ bytes_read = read(fd, buffer, sizeof(buffer)); printf("0x%06x : ", offset); for(i=0; i<bytes_read; ++i) { printf("%c ", buffer[i]); } printf("\n"); offset = offset + bytes_read; }while(bytes_read == sizeof(buffer)); 

Maintenant, en cours d’exécution, je donne un nom de fichier qui n’existe pas. Il imprime une sorte de données mélangées avec des variables d’environnement et une erreur de segmentation à la fin.

Comment est-ce possible? Quelle est l’impression du programme?

Merci John

read renvoie -1 car fd n’est pas valide, vous le stockez dans bytes_read qui est du type size_t qui n’est pas signé, donc votre boucle imprime (size_t) -1 caractères, ce qui est un nombre très important, bien plus grand que la taille du tampon. Ainsi, vous imprimez une grande partie de votre espace d’adresse, puis vous obtenez une erreur de segmentation lorsque vous atteignez la fin et que vous accédez à une adresse non valide.

Comme d’autres l’ont mentionné (sans répondre à votre question), vous devriez vérifier les résultats de la recherche d’une erreur. par exemple,

 int fd = open(argv[1], O_RDONLY); if( fd < 0 ){ fprintf(stderr, "error opening %s: %s\n", argv[1], strerror(errno)); exit(1); } 

Une mise en garde: si vous effectuez un autre appel système, ou appelez une routine susceptible de faire un appel système (par exemple, printf) avant d'appeler strerror, vous devez enregistrer errno et transmettre la copie enregistrée à strerror.

Une autre remarque à propos de votre programme:

 while(bytes_read == sizeof(buffer)) 

Ce n'est pas un bon test, car la lecture peut rapporter moins que le montant demandé. Votre boucle devrait continuer jusqu'à ce que read renvoie <= 0.

Il imprime les ordures parce que fd sera invariablement mis à -1 ce qui n’est pas une bonne chose à read car il ne fera rien d’autre que renvoyer -1. Cela laissera votre tampon intacte, ce qui signifie qu’il contient toutes les ordures que vous aviez à l’intérieur lorsque vous avez commencé.

Vous pourriez probablement mettre la boucle entière à l’intérieur de quelque chose comme:

 if (fd == -1) { printf ("error here"); } else { // do loop here } 

Vous devriez probablement vérifier que le descripteur de fichier renvoyé par open est valide avant de l’utiliser. Conformément à ces documents , vous devriez obtenir une réponse non négative pour un fichier valide. La lecture d’un descripteur non valide est probablement la source de votre problème.

Une fois cette opération terminée, la fonction open ouvre le fichier et renvoie un entier non négatif représentant le descripteur de fichier. Sinon, -1 doit être retourné et errno doit indiquer l’erreur. Donc, s’il vous plaît vérifier fd avant d’entrer dans la boucle pour effectuer la lecture.