2011-09-02 5 views
6
int main(int argc, char *argv[]) 
{ 
    FILE *fp = fopen("a.txt", "wt"); 

    fprintf(fp, "AAAA"); 

    // No flush. and No close 
    raise(SIGTERM); 

    exit(EXIT_SUCCESS); 
} 

result: No data has written to a.txtPerché i dati non vengono scaricati sul file all'uscita del processo?

mi aspettavo questo va bene. Perché il sistema chiuderà l'handle del file e quindi il driver del filesystem svuota i dati non spillati nel suo gestore Chiudi. Ma non lo era. Ho testato questo codice su EXT4, ubuntu 11.10

Domanda: Ho pensato che TUTTI i filesystem devono scaricare dati non aggiornati durante la sua elaborazione ravvicinata.
Posix non ha la regola?

P.S Questo codice ha funzionato bene (lavata bene) su NTFS, Win7

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    HANDLE h = CreateFile(L"D:\\a.txt", GENERIC_READ|GENERIC_WRITE, 
     0, 0, OPEN_ALWAYS, 0, 0); 
    BYTE a[3]; 
    memset(a, 'A', 3); 
    DWORD dw; 
    WriteFile(h, (PVOID)a, 3, &dw, 0); 

    TerminateProcess(GetCurrentProcess(), 1); 
    return 0; 
} 

Edit:
ho provato di nuovo con sistema di chiamata write. Ed è stato lavato bene.

int main(int argc, char** argv) 
{ 
    int fd = open("a.txt", O_CREAT|O_TRUNC|O_WRONLY); 
    char buf[3]; 
    memset(buf, 'A', 3); 
    size_t result = write(fd, buf, 3); 

    raise(SIGTERM); 
    exit(EXIT_SUCCESS); 
    return 0; 
} 

risposta

5

Non ha nulla a che fare con i driver del file system. Il problema è che il CRT sta memorizzando il flusso del file stesso. Imposta la dimensione del buffer con setvbuf(), usa un valore predefinito se non usi questa funzione.Non c'è buffer nell'applicazione quando si utilizza WriteFile(), l'output viene memorizzato nel buffer nella cache del file system del sistema operativo. Immune da ab improvvisi app.

Dovrai chiamare fflush() per ottenere lo stesso risultato.

7

Questo non è niente a che fare con il file system, piuttosto è il comportamento della implementazione C in uso che determina quando i flussi aperti sono arrossato o meno.

Sotto POSIX, l'azione azione predefinita per il segnale SIGTERM è:

interruzione anomala del processo. Il processo viene terminato con tutte le conseguenze di _exit() ...

_exit() equivale a _Exit() secondo lo standard C e la scelta di se irrigare flussi non è specificato dallo standard:

Le funzioni _Exit() e _exit() non chiamano funzioni registrate con atexit() né alcun gestore di segnale registrato. Sia i flussi aperti vengono lavati o chiusi, o file temporanei vengono rimossi è definito dall'implementazione ...

Supponendo che si sta utilizzando glibc su Linux, dal documentation (sottolineatura mia):

Quando un processo termina, per qualsiasi motivo, o perché il programma termina, o come risultato di un segnale-succedono le seguenti cose:

  • Tutti i descrittori di file aperti nel processo sono chiusi. Vedi I/O a basso livello. Si noti che gli stream non vengono scaricati automaticamente quando il processo termina; vedi I/O su stream.

Non ho dimestichezza con il Windows' WriteFile e TerminateProcess quindi non posso commentare ciò che il comportamento documentato è.

+0

Grazie, lo testerò di nuovo con le chiamate di sistema, non crt, quando arrivo a casa – Benjamin