Pourquoi les données ne sont-elles pas vidées pour être classées à la sortie du processus?

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

Je m’attendais à ça. Parce que le système va fermer le descripteur de fichier et que le pilote du système de fichiers vide les données non nettoyées dans son gestionnaire Close. Mais ce n’était pas le cas. J’ai testé ce code sur EXT4, Ubuntu 11.10

Question: Je pensais que TOUS les systèmes de fichiers doivent vider les données non nettoyées lors de son traitement.
Posix n’a pas la règle?

PS Ce code a bien fonctionné (bien vidé) sur 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; } 

Modifier:
Je l’ai testé à nouveau avec l’ write appel système. Et il a été bien rincé.

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

Cela n’a rien à voir avec les pilotes de système de fichiers. Le problème est que le CRT met en mémoire tampon le stream de fichiers lui-même. Vous définissez la taille du tampon avec setvbuf (), il utilise un défaut si vous n’utilisez pas cette fonction. Il n’y a pas de mise en mémoire tampon dans l’application lorsque vous utilisez WriteFile (), la sortie est mise en mémoire tampon dans le cache du système de fichiers du système d’exploitation. Immunité contre les avortements brutaux.

Vous devrez appeler fflush () pour obtenir la même chose.

Cela n’a rien à voir avec le système de fichiers, c’est plutôt le comportement de l’implémentation C que vous utilisez qui détermine si les stream ouverts sont vidés ou non.

Sous POSIX, l’action d’action par défaut pour le signal SIGTERM est la suivante:

Terminaison anormale du processus. Le processus est terminé avec toutes les conséquences de _exit () …

_exit() est équivalent à _Exit() selon le standard C et le choix de vider les stream n’est pas spécifié par la norme:

Les fonctions _Exit () et _exit () ne doivent pas appeler les fonctions enregistrées avec atexit () ni les gestionnaires de signaux enregistrés. Si les stream ouverts sont vidés ou fermés, ou si les fichiers temporaires sont supprimés, cela est défini par l’implémentation …

En supposant que vous utilisez glibc sous Linux, à partir de la documentation (c’est moi qui souligne):

Lorsqu’un processus se termine pour une raison quelconque, soit parce que le programme se termine, soit à la suite d’un signal, les événements suivants se produisent:

  • Tous les descripteurs de fichiers ouverts dans le processus sont fermés. Voir E / S de bas niveau. Notez que les stream ne sont pas vidés automatiquement lorsque le processus se termine ; voir E / S sur les stream.

Je ne suis pas familier avec Windows WriteFile et TerminateProcess donc je ne peux pas commenter le comportement documenté.