J'ai besoin de fermer stdout et stardr pour l'un de mes programmes C. Comment est-il possible sans quitter le programme dans l'exécution? P>
5 Réponses :
Qu'avez-vous essayé? Ne fclose code> fonctionne pas? P>
@LHF Alors comment l'ouvrir à nouveau?
@tropy, il n'y a aucun moyen de l'ouvrir à nouveau.
Vous pouvez le rouvrir en utilisant Freopen ("/ dev / tty", "W", stdout); Ceci est souvent utilisé si un appel à exécuté échoue.
Fermer l'un des 3 flux par défaut dangereux, avec des ramifications potentiellement persistantes pour la machine réelle que vous avez exécutable?
Vous pouvez simplement:
fclose(stdout); fclose(stderr);
... la raison de le faire est de dissocier le processus du TTY qui l'a débuté (s'il a été démarré à partir d'un TTY).
Les fermer sans ouvrir un remplacement (par exemple / dev / null code>) est une très mauvaise idée et généralement dangereuse.
Vous avez la raison de la raison. L'écriture sur un fichier fermé code> (STDIO Stream) est UB, mais écrire dans un descripteur de fichier fermé est juste
eBadf code>. En tout état de cause, la raison plus importante est qu'une autre partie du processus de programme ou d'enfant pourrait ouvrir ultérieurement un fichier important, qui sera attribué au premier numéro de descripteur de fichier non utilisé. Si FD 0, 1 ou 2 est inutilisé, le nouveau descripteur de fichier prendra la place de STDIN, STDOUT ou STDRERR, et pourrait être encombré par une autre partie du programme (ou processus enfant) qui utilise l'un de ces éléments pour leur habituel. Des fins ...
-1. C'est toujours un mauvais conseil et cela s'allume sur Google. NE PAS I> FCLOSE STDERR, c'est probablement un mauvais bogue. freopen () code> starr to / dev / null ou do
DUP2 (Somenullfd, 2) code>.
@Nicholaswilson Oui, je sais. J'ai abordé cette question à l'époque, cependant, pour le rendre plus explicite, j'ai rééclamé la réponse à intégrer tous les commentaires ci-dessus.
Si vous souhaitez empêcher votre application d'écrire à la console, alors: sorties: p>
Ce code a un comportement indéfini (à l'aide d'un fichier * code> une fois le fichier fermé). Cela pourrait tout aussi bien planter ou pire.
@R Cette partie du code que vous avez mentionné est juste pour illustrer ce que l'application fait depuis que le questionneur n'a pas répondu à nos commentaires sur ce qu'il devrait arriver après la fermeture de Stdout / Stdout. Puisque j'ai ajouté un avertissement dans la réponse à ce sujet, je ne suis pas sûr que je mérite toujours le -1, mais merci de toute façon.
J'ai enlevé le -1, mais "fera" est toujours erroné. En disant que c'est ce qu'il "pourrait faire" serait mieux, mais de toute façon, vous devez noter que le code exemple a comportement non défini i> et est un programme incorrect.
Avertissement: Je ne suis pas expérimenté dans C du tout, mais a récemment lu une diapositive qui répond directement à cette question directement par Jim Meyering, un employé de Redhat et Gnulib Mainteneur: https://www.gnu.org/ghm/2011/paris/slides/jim-meyering-goodbye -world.pdf . Je suis simplement résumée. Em> Obtenez closeout.c et ses dépendances de gnulib dans votre source et appelle p> comme votre première ligne dans la principale. P> Premièrement, certains avertissements de tête, citant POSIX < / a>: p> puisque après l'appel à FLOSE () Toute utilisation des flux entraîne un comportement non défini, FCLose () ne doit pas être utilisé sur STDIN, STDOUT ou STDERR, sauf immédiatement avant la résiliation du processus, ...... s'il y en a Atexit () Les gestionnaires enregistrés par l'application, un tel appel à FLOSE () ne doit pas se produire tant que le dernier gestionnaire est terminé. Une fois que FLOSE () a été utilisé pour fermer Stdin, STDOUT ou STDRERR, il n'y a pas de moyen standard de rouvrir l'un de ces flux. P>
Utilisation de Fermer () sur des descripteurs de fichier STDIN_FILENO, stdout_fileno ou stardr_fileno doit immédiatement être suivi d'une opération pour rouvrir ces descripteurs de fichiers. ...... En outre, une approche () suivie d'une opération de réouverture (par exemple ouvert (), dup (), etc.) n'est pas atomique; DUP2 () doit être utilisé pour modifier les descripteurs de fichiers standard. P>
BlockQuote> Le flux de fermeture sans manipuler ses erreurs n'est pas robuste, et c'est la même chose pour stdout et stardr. Voici une liste d'erreurs dont vous avez besoin pour gérer: p> gérer ces erreurs, comme le gnulib implémente dans fermer-stream.c , est cité ci-dessous. p> AVIS: ps: p> Je voulais juste diriger la sortie STDOUT et STDERR dans un fichier journal au lieu de la console. P>
blockQuote> Ce n'est pas une bonne raison de fermer stdout et stardr si vous écrivez un démon selon http://cloud9.hedgee.com./scribbles/daemon#logging . Vous devriez laisser un gestionnaire de daemon (tel que Daemon Tools, Runit, S6, Nosh, OpenRC et SystemD) gérer la redirection. P> Cependant, vous devez toujours fermer n'importe quel flux que le programme a déjà écrit dans le fin pour vérifier les erreurs. Devis de près de Fermer-Stream.c: P> Si un programme écrit n'importe quoi em> au flux, ce programme devrait fermer
Streamez et assurez-vous qu'il réussit avant de quitter. Sinon,
Supposons que vous alliez à l'extrême de vérifier le statut de retour
de chaque fonction qui fait une écriture explicite au flux. Le dernier
Printf peut réussir par écrit au tampon de flux interne, et pourtant
Le FCLOSE (Stream) pourrait toujours échouer (dû par exemple, à une erreur complète de disque)
quand il essaie d'écrire ces données tamponnées. Ainsi, vous seriez
laissé avec un fichier de sortie incomplet et le programme incriminé
Sortez avec succès. Même appeler fflush n'est pas toujours suffisant,
Depuis quelques données écrites / rinçues de systèmes de fichiers (NFS et CODA)
jusqu'à un appel étroit réel. P>
En plus, il est inutile de vérifier la valeur de retour de chaque appel
qui écrit pour ruisseau - laissez simplement l'enregistrement de l'état du flux interne
l'échec. C'est ce que le test FERROR vérifie ci-dessous. P>
blockQuote> p> tl; dr h3>
Résumé h3>
fclose (stdout) code> li>
ferror (stdout) code> a.k.a. Erreur précédente Li>
__ fdpending (stdout) code> a.k.a. des trucs non rincé li>
ul>
__ FRPENDING code> est spécial à GLIBC et n'est peut-être pas être portable. Otoh, c'est sur le chemin d'être normalisé a > comme
fpentre code>. p>
En réalité, vous pouvez également utiliser la fonction fermeture code>:
Pourquoi voulez-vous les fermer? Qu'espérez vous accomplir?
Que vous attendez-vous lorsque vous les fermez?
@Joseph il pourrait vouloir mettre le processus en arrière-plan. Dans ce cas, vous ferez toujours mieux de fermer tous les descripteurs de fichiers standard afin que vous ne finissez pas les avoir invalidés.
Je voulais juste diriger la sortie STDOUT et STDERR dans un fichier journal au lieu de la console. Désolé d'avoir répondu tard. Je l'ai travaillé maintenant.