c - Hvorfor bliver data ikke skyllet til fil på procesudgang?

Indlæg af Hanne Mølgaard Plasc

Problem



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.txt


Jeg forventede det var fint. Fordi systemet lukker filhåndtaget, skyller filsystemdriveren de ikke-spolede data i sin Close-handler. Men det var det ikke.
Jeg testede denne kode på EXT4, ubuntu 11.10


Spørgsmål:
Jeg troede, at ALLE filsystemer skal skylle ufløjede data ved sin nøjagtige behandling.

Posix har ikke reglen?


P.S Denne kode fungerede godt (skyllet godt) på 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;
}




Jeg testede det igen med systemopkald write. Og det blev skyllet godt.


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;
}

Bedste reference


Det har ikke noget at gøre med filsystemdrivere. Problemet er, at CRT buffrer selve filmen. Du indstiller bufferstørrelsen med setvbuf (), den bruger en standard, hvis du ikke bruger denne funktion. Der er ingen buffer i applikationen, når du bruger WriteFile (), output er buffer i operativsystemets filsystem cache. Immun fra abrupt app afbrydes.


Du skal ringe fflush () for at opnå det samme.

Andre referencer 1


Dette er ikke noget at gøre med filsystemet, snarere er det adfærden til den C-implementering, du bruger, der bestemmer, når åbne strømme er skyllet eller ej.


Under POSIX er standard handling for SIGTERM signalet:



  Unormal afslutning af processen. Processen afsluttes med alle konsekvenserne af \_exit () ...



\_exit() svarer til \_Exit() i henhold til C-standarden, og valget af, om der skal spylles strømme, er ikke angivet af standarden:



  Funktionerne \_Exit () og \_exit () må ikke kalde funktioner registreret med atexit () eller nogen registrerede signalhåndteringsfunktioner. Uanset om åbne strømme er skyllet eller lukket, eller midlertidige filer fjernes, er implementeringsdefineret ...



Forudsat at du bruger glibc på Linux, fra dokumentationen (vægt min): [11]



  Når en proces afsluttes af en eller anden grund - enten fordi programmet afsluttes eller som et resultat af et signal - sker følgende ting:

  
  

      
  • Alle åbne filbeskrivere i processen er lukket. Se Lavniveau I/O. Bemærk, at strømme ikke skylles automatisk, når processen afsluttes ; se I/O på streams.

  •   



Jeg er ikke bekendt med Windows'en WriteFile og TerminateProcess, så jeg kan ikke kommentere hvad den dokumenterede opførsel er.