Question

Voici mon code :

#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>
int main(int argc,char *argv[])
{
  int oldfd;
  int newfd;
  if(argc!=2)
  {
    printf("Usgae : %s file_name\n",argv[0]);
    exit(0);
  }
 oldfd=open(argv[1],O_RDWR|O_APPEND,S_IRWXU); // Opening the file in Read/Write mode
 if (-1 == oldfd)
 {
  perror("Error opening file");
  exit(0);
 }
 close(1); // closing stdout 
 newfd=dup(oldfd); //Now this newfd holds the value 1 
 close(oldfd); //closing the oldfd
 printf("\nStack Overflow"); //Now this printf will print content into the file as stdout closed already
 close(newfd);// closing newfd 
 return 0;
}

Ce que j'essaie en fait de faire, c'est simplement d'imprimer "Stack Overflow" dans le fichier en utilisant printf() au lieu de l'appel système write().

Il n'imprime pas le contenu dans le fichier.Mais une chose que j'ai observée est que si je supprime le code :

 close(newfd)

Il imprime le contenu dans le fichier comme prévu.Mais je n'arrive pas à comprendre pourquoi.J'ai imprimé le contenu et ensuite seulement je ferme le newfd.

Quelle en est la raison ?

Était-ce utile?

La solution

Ce qui se passe réellement ici, c'est que printfLa sortie de est mise en mémoire tampon et n'est pas envoyée immédiatement à fd 1 ;à la place, le tampon est vidé vers le descripteur de fichier 1 par le runtime C après votre retour de main.Si tu close(newfd), vous avez effectivement obstrué le vidage automatique qui est autrement effectué par le runtime à la sortie.

Si vous explicitement fflush(stdout) Avant toi close(newfd), votre sortie devrait apparaître dans le fichier.

À propos, si vous souhaitez rediriger un descripteur de fichier spécifique, il existe un autre appel système dup2(oldfd, 1) ce qui fait de fd 1 un double de oldfd, fermant le fd 1 s'il était précédemment ouvert.

Autres conseils

Lorsque vous utilisez directement des descripteurs de fichiers, vous voudrez éviter d'utiliser les fonctions C stdio telles que printf.Changer le descripteur de fichier sous-jacent de sous la couche stdio semble très périlleux.

Si vous modifiez votre générique code-étiquette comme suit:

write(newfd, "\nStack Overflow", 15);

alors vous obtiendrez probablement le résultat que vous attendez (que ce soit votre printf ou non).

close, write, open sont appels système principalement fait à l'intérieur du noyau Linux;donc du point de vue applicatif, ce sont des opérations atomiques élémentaires.

printf et fprintf sont des fonctions de bibliothèque standard construites au-dessus de ces appels système (et d'autres).

Avant sortie-ing (par ex.revenant de main), la bibliothèque standard et l'environnement (notamment le code dans crt*.o appeler votre main) exécute les fonctions enregistrées par une sortie;et l'E/S standard enregistre (en quelque sorte) un appel à affleurer à l'heure de la sortie.Alors le stdout est fflush-ed à l'heure de sortie.Si tu close son descripteur principal, ce vidage échoue et ne fait rien.

je pense qu'il ne faut pas mélanger stdio et cru write-s au même descripteur d'écriture.Pensez à utiliser fdopen ou freopen

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top