Vérifier si un fichier a été ouvert avec fopen a été fermé
gcc (GCC) 4.7.2
c89
Est-il possible de vérifier si un fichier a déjà fermé?
J'ai ouvert un fichier à l'aide de fopen()
et fermé à l'aide de fclose(fd)
.
Ce fichier est ouvert et fermé lors de l'exécution du programme. Toutefois, l'utilisateur peut mettre fin au programme en faisant un ctrl-c
.
Quand je vais à ma routine de nettoyage, je ne sais pas si le fichier est dans un état ouvert ou fermé. Donc, si je fais un fclose(fd)
deux fois, il va vidage de pile.
Quelques idées que j'ai été jeter autour de:
- Ajouter un état vers le fichier doit être ouvert ou fermé, puis vérifiez que l'état, signifie plus de travail pour un travail simple.
- Ne rien faire comme les OS de nettoyage automatially lorsque le programme se termine.
- Est il est de la fonction d'accès, mais qui se vérifie juste la mode.
Merci beaucoup à l'avance,
L'ajout d'un état (la première option) permettrait d'ajouter une condition de course, sauf si vous masque Ctrl+C signal alors que l'état est synchronisé avec le fichier.
pourquoi ne pouvez-vous pas ensemble
Il est plus liée à la libc (souvent Glibc, mais il pourrait être la musl-libc etc...) que pour le compilateur.
Avoir un état var
pourquoi ne pouvez-vous pas ensemble
fd
(nom étrange, d'ailleurs) pour NULL
après la fermeture ?Il est plus liée à la libc (souvent Glibc, mais il pourrait être la musl-libc etc...) que pour le compilateur.
Avoir un état var
#define
d comme OPEN
et CLOSE
. Chaque fois que vous appelez fopen
dans votre code, définir l'état comme Current_State = OPEN;
et lorsque vous appelez fclose
dans votre code, définir l'état comme Current_State = CLOSE;
et de l'utilisation que current_state
variable comme et quand nécessaire.OriginalL'auteur ant2009 | 2013-07-30
Vous devez vous connecter pour publier un commentaire.
Autant que je sache, la glibc ne fournit pas une méthode pour valider un
FILE*
variable.Garder une sorte d'état ou tout simplement la mise en
fd
àNULL
fonctionne, mais vous devez être prudent de ne pas entrer dans votre routine de nettoyage juste après la fermeture du fichier, mais avant de réinitialiserfd
. Comme Ctrl+C envoie un signal (SIGINT) à un programme, vous pouvez simplement bloquer le signal alors que le fichier est fermé et fd est en cours de réinitialisation. Donc, votrefclose
dans le programme principal doit ressembler à:Et dans votre routine de nettoyage, vous devez juste vérifier
fd
:Si votre programme est multithread, vous devez utiliser
pthread_sigmask
à la place.Dans votre cas, le simple appel de
fcloseall()
dans la routine de nettoyage serait beaucoup plus facile.Que pour la deuxième option implique dans votre question, à propos de ne rien faire - ainsi, le système d'exploitation de nettoyage tout pour votre programme. Ensuite, seul inconvénient, c'est que si on ouvre écrire des ruisseaux, des données risquent de ne pas être écrites sur le disque. Mais peut-être dans le cas de Ctrl+C c'est juste ok.
Autant que je sache, autant que je sache est une abréviation de 'je sais' 🙂
Merci, je ne savais
OriginalL'auteur Inspired
Il coutures pour moi qu'il y a un peu de confusion dans votre esprit.
Des gestionnaires de fichiers, utilisé avec
fopen
,fclose
,f...
fonctions sont portée et les processus de. I. e., ils sont valables au sein de l'application (normalement).Deux choses peuvent se produire lorsque vous ouvrez un fichier: vous réussir ou pas. Si vous réussissez, vous pouvez être en utilisant le fichier de manière exclusive ou partagée avec d'autres processus. Si vous échouez, peut-être un autre processus est déjà à l'aide de fichier. Recherche
_fsopen
.Lorsque le processus se termine, normalement ou interrompu (comme avec
Ctrl+C
), OS libère les ressources associées au processus, tôt ou tard. Cela s'applique à des gestionnaires de fichiers, mémoire, ...Concernant votre question, si votre application fin normalement ou avec
Ctrl+C
, unclosed des gestionnaires de fichiers vont être libérés par l'OS.À chaque fois que votre application démarre, vous devez ouvrir des gestionnaires de fichiers dont vous avez besoin. OS ne sera pas à les garder ouverts pour vous.
OriginalL'auteur LS_ᴅᴇᴠ
J'ai eu un problème similaire dans une situation différente (pas de condition de course). Donc, cette solution couvre à la fois la question dans le titre et celui demandé par ant.
Quand
fclose(fd)
est appelé l'internefd->_fileno
faible niveau I/O-descripteur de fichier est définie sur -1 (ou d'une autre invalide unix descripteur de fichier). Donc, on a pu vérifier à l'aide defileno(fd)>=0
pour vérifier sifd
est toujours valable (flux de mon problème d'origine).Quand
CTRL-C
est appuyé sur le processus reçoit un signal à comité de lecture commeSIGINT
et exécute le correspondant gestionnaire de signal (par exemple, une fonction prédéfinie). On ne devrait jamais essayer de faire tout ce qui concernait le programme de l'état (sauf pour l'réglable variables, par exemple des drapeaux) dans un gestionnaire de signal, parce que le signal peut arriver dans n'importe quelle situation, donc, même sifclose(fd)
est exécuté dans la glibc (doncfd->_fileno
est pas défini au cours de l'exécution du gestionnaire). De ce fait, la manière canonique ici est de définir un indicateur de déclenchement de l'arrêt et de retour. L'application principale est alors nécessaire de vérifier ce drapeau suffisamment souvent, et, si elle est définie, nettoie et à la sortie.Ce programme se termine après
CTRL-C
est pressé, sans aboutir à une fd nettoyé par le système.OriginalL'auteur msebas
Peut être vous aider, juste quelques suggestions:
Vous pouvez vérifier l'ouverture de fichier par votre processus à l'aide de l'identifiant du processus.
pid_t getpid(void);
, retourner l'ID de processus du processus appelant.pfiles
commande.Deuxième:
Vous pouvez appeler
int fcloseall (void);
avant le programme se termine./proc/self/fd/
et/proc/self/fdinfo/
répertoires à partir de l'intérieur du processus, ou/proc/$PID/fd/
etc à partir de l'extérieur./proc/
est accessible parpfiles
Est je l'ai lu dans le manuel de
pfiles
commande lire proc système de fichiersOriginalL'auteur Grijesh Chauhan
Puis l'ajouter à
main
:De le faire avant fcolse:
Et définir
fdOpen = 0 ;
après la fermeture de fichier normalement//SIGINT will not interrupt us now.
Puis
Donc nous faire un peu de ménage emplois, puis quittez le programme à
sig_int
.fclose
, mais avantfdOpen = 0;
.Ouais .vous êtes de droite.
OriginalL'auteur Lidong Guo