Le 10/11/15 07:24, Richard PALO a écrit :
> Le 10/11/15 06:58, Garrett D'Amore a écrit :
>> I wonder if this depends on the version of Python in use.  Also the changes 
>> to reuse files may be significant.  Posix says files are synced to disk at 
>> close time.  If the files are not closed then what actually makes sure the 
>> content is written to disk?
>>
> 
> My feeling is the same, flush() or worst case disabling buffering if justified
> is the only sane and safe way.
> 
> I'm not suggesting that there is an issue in illumos, but I'm real curious as 
> to 
> why Oracle states that S12 doesn't experience the issue.
> 
> Not sure what version of python S12 uses, but I use 2.6 (native omnios) and 
> 2.7
> (my prefered version in pkgsrc).  From what ixquick finds for me, python 3 
> probably
> behaves identically (and should, reasonably).
> 

This has turned into an interesting discussion: 
https://selenic.com/pipermail/mercurial-devel/2015-December/076589.html

Just to see if I could reproduce in plain C the purported issue, I hacked the 
attached C test program.

Compiled normally seems to demonstrate that the second string doesn't seem to 
be written.
with -DH1, a fflush() seems to do the job.
-DH2 is just to see if fseek()'ing to EOF helps, but it doesn't seem to.
> richard@omnis:/home/richard/src/tio$ gcc tseek.c -o tseek
> richard@omnis:/home/richard/src/tio$ rm foo 
> richard@omnis:/home/richard/src/tio$ ./tseek foo hello there!
> wrote 5 bytes
> read: 5, offset: 5
> wrote 6 bytes
> seeked to the beginning, offset: 0
> read: 5, offset: 5
> richard@omnis:/home/richard/src/tio$ ./tseek foo hello there!
> wrote 5 bytes
> read: 10, offset: 10
> wrote 6 bytes
> seeked to the beginning, offset: 0
> read: 10, offset: 10
> richard@omnis:/home/richard/src/tio$ gcc tseek.c -o tseek -DH1
> richard@omnis:/home/richard/src/tio$ rm foo 
> richard@omnis:/home/richard/src/tio$ ./tseek foo hello there!
> wrote 5 bytes
> read: 5, offset: 5
> wrote 6 bytes
> seeked to the beginning, offset: 0
> read: 11, offset: 11
> richard@omnis:/home/richard/src/tio$ ./tseek foo hello there!
> wrote 5 bytes
> read: 16, offset: 16
> wrote 6 bytes
> seeked to the beginning, offset: 0
> read: 22, offset: 22
> richard@omnis:/home/richard/src/tio$ gcc tseek.c -o tseek -DH2
> richard@omnis:/home/richard/src/tio$ rm foo 
> richard@omnis:/home/richard/src/tio$ ./tseek foo hello there!
> wrote 5 bytes
> read: 5, offset: 5
> wrote 6 bytes
> seeked to the beginning, offset: 0
> read: 5, offset: 5
> richard@omnis:/home/richard/src/tio$ ./tseek foo hello there!
> wrote 5 bytes
> read: 10, offset: 10
> wrote 6 bytes
> seeked to the beginning, offset: 0
> read: 10, offset: 10

From fseek() manpage:
...
>        If the most recent operation, other than ftell(3C), on a given stream
>        is fflush(3C), the file offset in the underlying open file description
>        will be adjusted to reflect the location specified by fseek().
this seems normal, but -- a bit further:
>        If the stream is writable and buffered data had not been written to the
>        underlying file, fseek() will cause the unwritten data to be written to
>        the file and mark the st_ctime and st_mtime fields of the file for
>        update.

this seems to suggest that the fseek() does an implicit flush, but it doesn't.

Is the problem in code, in the manpage, or in the implementation?

BTW, if I test on NetBSD, the test program built without hacks seems to work 
fine.

-- 
Richard PALO




-------------------------------------------
illumos-discuss
Archives: https://www.listbox.com/member/archive/182180/=now
RSS Feed: https://www.listbox.com/member/archive/rss/182180/21175430-2e6923be
Modify Your Subscription: 
https://www.listbox.com/member/?member_id=21175430&id_secret=21175430-6a77cda4
Powered by Listbox: http://www.listbox.com
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
main(int argc, char **argv)
{
	FILE *fp;

	if (argc != 4) {
		printf("try again, syntax: %s <filename> string1 string2\n",
		    argv[0]);
		exit (1);
	}

	fp = fopen(argv[1], "a+b");
	if (fp != NULL) {
		char buffer[2048];
		int br, bw;

		/* start at the end of the file to allow appending */
		(void) fseek(fp, 0, SEEK_END);

		bw = fwrite(argv[2], 1, strlen(argv[2]), fp);
		printf("wrote %d bytes\n", bw);

		if (fseek(fp, 0, SEEK_SET))
			perror("1st fseek");

		br = fread(buffer, 1, sizeof(buffer), fp);
		if (br != 0) {
			printf("read: %d, offset: %d\n",
			    br, (int)ftell(fp));
		} else if ( ferror(fp) ) {
			perror("fread");
		} else if ( feof(fp) ) {
			printf("end of file, read: %d\n", br);
		}

		bw = fwrite( argv[3], 1, strlen(argv[3]), fp);
		printf("wrote %d bytes\n", bw);

#ifdef	H1
		(void) fflush(fp);
#elif	H2
		if (fseek(fp, 0, SEEK_END))
			perror("H2 fseek");
#endif
		/* the following seek should automatically flush() */
		if (fseek(fp, 0, SEEK_SET))
			perror("2nd fseek");

		printf ("seeked to the beginning, offset: %d\n",
		    (int)ftell(fp));
		
		br = fread(buffer, 1, sizeof(buffer), fp);
		if (br != 0) {
			printf("read: %d, offset: %d\n",
			    br, (int)ftell(fp));
		} else if ( ferror(fp) ) {
			perror("fread");
		} else if ( feof(fp) ) {
			printf("end of file, read: %d\n", br);
		}

		(void) fclose(fp);
		exit(0);
	} else {
		perror(argv[1]);
		exit(1);
	}
}

Reply via email to