Domanda

CreateFile ha FILE_FLAG_DELETE_ON_CLOSE , ma sono su Linux.

Voglio aprire un file temporaneo che verrà sempre cancellato al termine del programma. Potrei capire che nel caso di un arresto del programma potrebbe non essere pratico garantirlo, ma in ogni altro caso mi piacerebbe che funzionasse.

So di RAII. Conosco i segnali. Conosco atexit (3) . So di poter aprire il file ed eliminarlo immediatamente e il file rimarrà accessibile fino alla chiusura del descrittore di file (che gestisce anche un arresto anomalo). Nessuna di queste sembra una soluzione completa e diretta:

  1. RAII: ci sono stato, fatto quello: ho un oggetto il cui distruttore cancella il file, ma il distruttore non viene chiamato se il programma viene terminato da un segnale.
  2. segnali: sto scrivendo una libreria di basso livello che rende la registrazione di un gestore di segnali una proposta difficile. Ad esempio, cosa succede se l'applicazione utilizza i segnali stessi? Non voglio calpestare le dita dei piedi. Potrei prendere in considerazione un uso intelligente di sigaction (2) per farcela ... ma non ho ancora pensato abbastanza a questa possibilità.
  3. atexit (3) : apparentemente inutile, poiché non viene chiamato durante la terminazione anomala (ad es. tramite un segnale).
  4. preventivo (2) : questo è abbastanza buono, tranne per il fatto che ho bisogno che il file rimanga visibile nel filesystem (altrimenti il ??sistema è più difficile da monitorare / risolvere).

Cosa faresti qui?

Altre spiegazioni

Ho eluso un dettaglio nel mio post originale che ora capisco che avrei dovuto includere. Il " file " in questo caso non è strettamente un file normale, ma piuttosto una coda di messaggi POSIX. Lo creo tramite mq_open () . Può essere chiuso tramite mq_close () o close () (il primo è un alias per il secondo sul mio sistema). Può essere rimosso dal sistema tramite mq_unlink () . Tutto ciò rende analogo a un file normale, tranne che non riesco a scegliere la directory in cui risiede il file. Ciò rende la risposta corrente più popolare (collocando il file in / tmp ) non realizzabile, poiché il file " file " viene creato dal sistema in un filesystem virtuale con capacità molto limitata. (Ho montato il filesystem virtuale in / dev / mqueue , seguendo l'esempio in man mq_overview ).

Questo spiega anche perché ho bisogno che il nome rimanga visibile (rendendo inattuabile l'approccio di scollegamento immediato): il "file" " deve essere condiviso tra due o più processi.

È stato utile?

Soluzione

Il requisito che il nome rimanga visibile mentre il processo è in esecuzione rende questo difficile da raggiungere. Puoi rivisitare tale requisito?

In caso contrario, probabilmente non esiste una soluzione perfetta. Vorrei prendere in considerazione la combinazione di una strategia di gestione del segnale con ciò che suggerisce Kamil Kisiel. È possibile tenere traccia dei gestori dei segnali installati prima di installare i gestori dei segnali. Se il gestore predefinito è SIG_IGN, normalmente non si installa il proprio gestore; se è SIG_DFL, te lo ricorderesti; se è qualcos'altro - un gestore di segnali definito dall'utente - ricorderai quel puntatore e installerai il tuo. Quando il tuo gestore veniva chiamato, facevi quello che dovevi fare, e poi chiamavi il gestore ricordato, concatenando così i gestori. Dovresti anche installare un gestore atexit (). Documenteresti anche che lo fai e i segnali per i quali lo fai.

Notare che la gestione del segnale è una strategia imperfetta; SIGKILL non può essere catturato e il gestore atexit () non verrà chiamato e il file verrà lasciato in giro.

Il suggerimento di David Segond - un demone nome file temporaneo - è interessante. Per processi semplici, è sufficiente; se il processo che richiede il file temporaneo esegue il fork e si aspetta che il figlio possieda il file da quel momento in poi (ed esca), il demone ha un problema nel rilevare quando l'ultimo processo che lo utilizza muore, perché non conosce automaticamente i processi che lo hanno aperto.

Altri suggerimenti

Se stai solo creando un file temporaneo, crealo in / tmp o in una sua sottodirectory. Quindi fai del tuo meglio per rimuoverlo quando lo fai tramite atexit (3) o simili. Fintanto che usi nomi univoci scelti tramite mkstemp (3) o simili anche se non viene eliminato a causa di un arresto anomalo del programma, non rischi di rileggerlo nelle esecuzioni successive o in altre condizioni simili .

A quel punto è solo un problema a livello di sistema di mantenere pulito / tmp . La maggior parte delle distro lo cancella all'avvio o allo spegnimento o esegue un normale cronjob per eliminare i vecchi file.

Forse qualcuno lo ha già suggerito, ma non sono in grado di individuarlo, dati tutti i tuoi requisiti, la cosa migliore che mi viene in mente è di avere il nome del file in qualche modo comunicato a un processo genitore, come uno script di avvio, che ripulire dopo la fine del processo, se non fosse riuscito a farlo. Questo è forse noto soprattutto come cane da guardia, ma poi con il caso d'uso più comune aggiunto per uccidere e / o riavviare il processo quando in qualche modo fallisce.

Se anche il tuo processo genitore muore, sei quasi sfortunato, ma la maggior parte degli ambienti di script sono abbastanza robusti e raramente muoiono a meno che lo script non sia rotto, che è spesso più facile da mantenere corretto di un programma.

In passato ho creato un "gestore file temporaneo" che ha tenuto traccia dei file temporanei.

Uno richiederebbe un nome di file temporaneo dal gestore e questo nome è stato registrato.

Quando non è più necessario il nome del file temporaneo, si informa il gestore e il nome file non è registrato.

Alla ricezione di un segnale di terminazione, tutti i file temporanei registrati sono stati distrutti.

I nomi di file temporanei erano basati su UUID per evitare collisioni.

Potresti avere il fork del processo dopo aver creato il file, quindi attendere che il figlio si chiuda, quindi il genitore può scollegare il file ed uscire.

Sono appena entrato in StackOverflow e ti ho trovato qui :)

Se il tuo problema è gestire i file mq e impedire che si accumulino, non è necessario garantire la cancellazione dei file al termine. Se volevi solo che i file inutili si accumulassero, tenere un diario potrebbe essere tutto ciò di cui hai bisogno. Aggiungi una voce al file journal dopo l'apertura di un mq, un'altra voce quando viene chiusa e quando la libreria viene inizializzata, controlla l'incoerenza nel journal e intraprendi qualsiasi azione necessaria per correggere l'incoerenza. Se ti preoccupi di un arresto anomalo quando viene chiamato mq_open / mq_close , puoi anche aggiungere una registrazione prima nota prima che vengano chiamate quelle funzioni.

  • Avere una directory di contabilità per i file temporanei nella directory dot.
  • Quando si crea un file temporaneo, creare innanzitutto il file di conservazione dei libri nella directory di conservazione dei libri che contiene il percorso o l'UUID del proprio file temporaneo.
  • Crea quel file temporaneo.
  • Quando il file temporaneo viene eliminato, quindi eliminare il file di conservazione dei libri.
  • All'avvio del programma, scansionare la directory di conservazione dei libri per eventuali file contenenti percorsi a file temporanei e provare a eliminarli se trovati, eliminano i file di conservazione dei libri.
  • (Registra rumorosamente se un passaggio fallisce.)

Non vedo modi per farlo in modo più semplice. Questa è la caldaia che deve essere seguita da qualsiasi programma di qualità della produzione; +500 linee facilmente.

scroll top