I rewrote a custom demo soft for this (see attachments).
# When trying to write data into a file on local filesystem # All data are writen onto the disk
./write_into /tmp/file.txt 3 [fnFileSave] Will try to write 3 byte(s) into [/tmp/file.txt] [fnFileSave] Opening first stream pointer on file [/tmp/file.txt] [fnFileSave] Wanted to write 3 byte(s), and 3 were written [fnFileSave] All data were written, but MAYBE not flushed yet (len <4k) [fnCheckFileWritable?] Opening 2nd stream pointer on file [/tmp/file.txt] in APPEND mode. [fnCheckFileWritable?] Closing 2nd stream pointer on file [/tmp/file.txt]. [fnFileSave] The flushing succeeded [fnFileSave] The closing succeeded [fnFileSave] stat() says that [/tmp/file.txt] size is : 3 byte(s) ./write_into /tmp/file.txt 5000 [fnFileSave] Will try to write 5000 byte(s) into [/tmp/file.txt] [fnFileSave] Opening first stream pointer on file [/tmp/file.txt] [fnFileSave] Wanted to write 5000 byte(s), and 5000 were written [fnFileSave] All data were written, but probably only partially flushed (len > 4k but not multiple of 4k) [fnCheckFileWritable?] Opening 2nd stream pointer on file [/tmp/file.txt] in APPEND mode. [fnCheckFileWritable?] Closing 2nd stream pointer on file [/tmp/file.txt]. [fnFileSave] The flushing succeeded [fnFileSave] The closing succeeded [fnFileSave] stat() says that [/tmp/file.txt] size is : 5000 byte(s) # When using gvfs + sftp over the same location, only the data automatically # flushed on write (each full block of 4kb) before the opening of the second # file pointer succeed, the remainging data are lost ./write_into /run/user/1000/gvfs/sftp\:host\=localhost\,user\=nicolas/tmp/file.txt 3 [fnFileSave] Will try to write 3 byte(s) into [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] [fnFileSave] Opening first stream pointer on file [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] [fnFileSave] Wanted to write 3 byte(s), and 3 were written [fnFileSave] All data were written, but MAYBE not flushed yet (len <4k) [fnCheckFileWritable?] Opening 2nd stream pointer on file [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] in APPEND mode. [fnCheckFileWritable?] Closing 2nd stream pointer on file [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt]. [fnFileSave] The flushing failed, file is probably truncated [fnFileSave] -> fflush: Operation not supported [fnFileSave] The closing succeeded [fnFileSave] stat() says that [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] size is : 0 byte(s) ./write_into /run/user/1000/gvfs/sftp\:host\=localhost\,user\=nicolas/tmp/file.txt 4096 [fnFileSave] Will try to write 4096 byte(s) into [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] [fnFileSave] Opening first stream pointer on file [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] [fnFileSave] Wanted to write 4096 byte(s), and 4096 were written [fnFileSave] All data were written, and probably flushed (len is multiple of 4k) [fnCheckFileWritable?] Opening 2nd stream pointer on file [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] in APPEND mode. [fnCheckFileWritable?] Closing 2nd stream pointer on file [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt]. [fnFileSave] The flushing succeeded [fnFileSave] The closing succeeded [fnFileSave] stat() says that [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] size is : 4096 byte(s) ./write_into /run/user/1000/gvfs/sftp\:host\=localhost\,user\=nicolas/tmp/file.txt 5000 [fnFileSave] Will try to write 5000 byte(s) into [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] [fnFileSave] Opening first stream pointer on file [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] [fnFileSave] Wanted to write 5000 byte(s), and 5000 were written [fnFileSave] All data were written, but probably only partially flushed (len > 4k but not multiple of 4k) [fnCheckFileWritable?] Opening 2nd stream pointer on file [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] in APPEND mode. [fnCheckFileWritable?] Closing 2nd stream pointer on file [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt]. [fnFileSave] The flushing failed, file is probably truncated [fnFileSave] -> fflush: Operation not supported [fnFileSave] The closing succeeded [fnFileSave] stat() says that [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] size is : 4096 byte(s) ./write_into /run/user/1000/gvfs/sftp\:host\=localhost\,user\=nicolas/tmp/file.txt 10000 [fnFileSave] Will try to write 10000 byte(s) into [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] [fnFileSave] Opening first stream pointer on file [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] [fnFileSave] Wanted to write 10000 byte(s), and 10000 were written [fnFileSave] All data were written, but probably only partially flushed (len > 4k but not multiple of 4k) [fnCheckFileWritable?] Opening 2nd stream pointer on file [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] in APPEND mode. [fnCheckFileWritable?] Closing 2nd stream pointer on file [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt]. [fnFileSave] The flushing failed, file is probably truncated [fnFileSave] -> fflush: Operation not supported [fnFileSave] The closing succeeded [fnFileSave] stat() says that [/run/user/1000/gvfs/sftp:host=localhost,user=nicolas/tmp/file.txt] size is : 8192 byte(s)
/* * Made to illustrate https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=680418 * compile with : gcc write_info.c -o write_info */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> /// Functions adapted from original leafpad source code (file.c) /// opens a file in APPEND mode to see if it's writable, then closes it int check_file_writable(char *filename) { FILE *fp; printf("[fnCheckFileWritable?] Opening 2nd stream pointer on file [%s] in APPEND mode.\n", filename); if ((fp = fopen(filename, "a")) != NULL) { printf("[fnCheckFileWritable?] Closing 2nd stream pointer on file [%s].\n", filename); if (fclose(fp) != 0) { perror("[fnCheckFileWritable?] \t-> fclose"); } return 1; } return 0; } int file_save(char* filename, int len) { FILE *fp; char *str, *cstr; int written, result; struct stat filestats; printf("[fnFileSave] Will try to write %d byte(s) into [%s]\n", len, filename); str = (char*) malloc (len*sizeof(char)); memset(str, 'X', len); printf("[fnFileSave] Opening first stream pointer on file [%s]\n", filename); fp = fopen(filename, "w"); if (!fp) { printf("[fnFileSave] Can't open file to write\n"); perror("[fnFileSave] \t-> fopen"); return -1; } written = fwrite(str, 1, len, fp); // not flushed yet printf("[fnFileSave] Wanted to write %d byte(s), and %d were written\n", len, written); if (written != len) { printf("[fnFileSave] Some data were lost\n"); perror("[fnFileSave] \t-> fwrite"); return -1; } else { if(len < 4096) printf("[fnFileSave] All data were written, but MAYBE not flushed yet (len <4k)\n"); else { if(len % 4096 == 0) printf("[fnFileSave] All data were written, and probably flushed (len is multiple of 4k)\n"); else printf("[fnFileSave] All data were written, but probably only partially flushed (len > 4k but not multiple of 4k)\n"); } } free(str); // As in leafpad 0.8.17, // a function opening a second handle on that file // in APPEND mode is called before the fclose(). // Only used to display strange behaviour in some case. check_file_writable(filename); // fclose() that also causes the flushing of unwritten data result = fflush(fp); if (result != 0) { printf("[fnFileSave] The flushing failed, file is probably truncated\n"); perror("[fnFileSave] \t-> fflush"); } else { printf("[fnFileSave] The flushing succeeded\n"); } result = fclose(fp); if (result != 0) { printf("[fnFileSave] The closing failed (%d)\n", result); perror("[fnFileSave] \t-> fclose"); } else { printf("[fnFileSave] The closing succeeded\n"); } if (stat(filename, &filestats) == -1) { perror("[fnFileSave] \t-> stat"); return -1; } printf("[fnFileSave] stat() says that [%s] size is : %lld byte(s)\n", filename, (long long) filestats.st_size ); return 0; } int main(int argc, char *argv[]) { if(argc != 3){ printf("That code try to write some content into a file."); printf("Syntax :\n"); printf("%s filename size\n", argv[0]); } else { char* filename = argv[1]; int len = atoi(argv[2]); if(len < 0) { printf("The size should be strictly positive\n"); exit(EXIT_FAILURE); } if(!file_save(filename, len)) exit(EXIT_FAILURE); } return EXIT_SUCCESS; }