7
votes

Utilisez FCLose to Tuyau de Popen est un bug grave?

Il y a quelques mois, j'écris une application CGI pour Linux qui utilise popen () code> pour lire la sortie d'une commande, puis je ferme le tuyau avec FCLose () code> .

Maintenant, j'ai lu que pour des pipes fermées est nécessaire à une utilisation pccle () code>. p>

Le manuel dit: P>

La valeur de retour de popen () code> est un flux d'E / S standard normal dans tout respects sauvegardez qu'il doit être fermé avec pclose () code> plutôt que FCLOSE (3) CODE>. P> blockQuote>

Mon code est comme ceci: P>

if ((NULL != (f = popen(command.value, "r")))) {
    //do something
    fclose(f);
}


4 commentaires

Vous avez un comportement indéfini: lisez pclose () vs fcfose () ? : la fonction _pclose Recherche l'ID de processus du processeur de commande (cmd.exe) démarré par le _Popen appel, exécute un _cwait appelez le nouveau processeur de commande et ferme le flux sur la tuyau associée.`


Il y a des postes sur votre question: 1. FLOSE () / pclose () peut bloquer sur certains pointeurs de fichiers et Quelle est la poigne de fermeture à UNIX? (fcfrose () de pclose ()) ?


Merci, je vais résoudre parce que c'est vraiment important. Maintenant, j'ai l'impact.


Sur Linux, le libc implémentation populaire est souvent un logiciel libre. J'étudie donc le code source de votre libc. Je suppose que non la téléphonie popen signifie que waikepid ne sera pas appelé, et vous aurez des processus zombies. Mais je vous laisse vérifier.


3 Réponses :


6
votes

Si vous utilisez FcLose sur le tuyau, vous aurez des fuites de descripteur de fichier, car FcLose ne libérera pas le pointeur de fichier dans le noyau (qui est créé lorsque vous créez le tuyau depuis son fichier).

Bien que vos tests ne puissent donc pas avoir montré aucun problème, exécutez votre programme 3000 fois (ou comment de nombreux descripteurs de fichiers sont autorisés, à la hausse de l'INT, je pense) et de regarder lorsque vous ne serez plus en mesure de créer des tuyaux.


1 commentaires

Typiquement fclose sur le flux de stddio réellement fait ferme le descripteur de tuyau sous-jacent (c'est caché dans FP -> _ Fileno ou quel que soit le champ nommé), C'est donc plus un zombie-proc-fuite qu'une fuite FD.



11
votes

Selon ce fil , en utilisant FCLOSE au lieu de pclose signifie que le processus à l'autre extrémité de la tuyau ne va pas récolter, il reste donc zombié.


1 commentaires

Très merci, alors je ne ferme pas la pipe, c'est mauvais, merci.



0
votes

Je viens de découvrir (après 10 ans) que j'utilisais par erreur FcLose pour certains Popen Appels, exécuté sur Windows 2008 Server. Ça a fonctionné (c'est-à-dire pas écrasé), et je me suis préoccupé par le code de retour sur ces appels de toute façon.

Mais j'avais besoin du code de retour du dernier Popen et fermer a été effectué correctement avec pclose . .

Il a l'effet étrange du retour d'un code d'erreur 0 (peut-être collecter le code retour du processus précédemment non peclose processus), même si la commande a échoué, créant un bogue très étrange dans le code, qui aurait pu conduire à des erreurs catastrophiques car l'appelant pense que le commandement a fonctionné.

Ce n'est pas seulement une question de descripteurs qui fuies, il peut introduire des bugs fonctionnels dans votre code (même si l'application fonctionne pendant quelques secondes et que vous ne vous souciez pas de fuites descripteurs)


4 commentaires

BTW, c'est un système d'exploitation très spécifique. L'OP a explicitement interrogé sur Linux. Et des distributions Linux habituelles ont un logiciel libre Libc, afin que l'OP devrait étudier le code source de sa mise en œuvre de la libc.


Ok, mais ce qui est arrivé pour moi sur Windows pourrait aussi se produire sur d'autres systèmes.


Sauf que l'aspect logiciel libre évolue beaucoup comment résoudre ce problème. Si votre LIBC (et votre noyau) était un logiciel libre, vous pouvez inspecter et étudier son code source (et comprendre ce qui se passe).


Oui. Mais même avec le code source, c'est clairement une erreur et il est facile de se réparer, alors ne laissez pas cela comme ça.