[Geany-devel] Changed file saving implementation for systems with GIO

Dimitar Zhekov dimitar.zhekov at xxxxx
Tue Nov 9 18:28:43 UTC 2010


On Tue, 9 Nov 2010 13:33:26 +0000
Nick Treleaven <nick.treleaven at btinternet.com> wrote:

> On Sat, 6 Nov 2010 11:33:41 +0200
> Dimitar Zhekov <dimitar.zhekov at gmail.com> wrote:
> 
> > I'll write a non-GIO variant first, as a proof of concept.
> 
> First, I feel quite reluctant to use non-GLib/GIO functions for writing
> instead of g_file_replace_contents because if there is a better
> implementation, why don't they add it?

That was discussed later and proven as not worth.

> > The current non-GIO is buggy anyway. First:
> > 
> > if (G_UNLIKELY(len != bytes_written))
> >         err = errno;
> > 
> > but fwrite() is not guaranteed to set errno, only write() is.
> > 
> > Second, and more important, the result of fclose() is not checked, for
> > a buffered file stream. On lack of disk space, on my system fwrite()
> > happily returns written == len, but fclose() fails. YMMV.
> > 
> > If not anything else, we should use non-buffered I/O, with fsync(), and
> > check the result of close() anyway.
> 
> Thanks for finding these problems. I accept fclose should be checked.
> 
> I'm not sure why write is better than fwrite - POSIX says both set
> errno.

Geany runs under Linux and Windows, possibly also under MAC and BSD.
None of Linux fwrite(3), MSVCRT, Darwin fwrite(3) and BSD fwrite(3)
mentions anything about setting errno.

> http://www.opengroup.org/onlinepubs/009695399/functions/fwrite.html

This is the 2004 Edition. Linux conforms to 2001, BSD/Darwin to 1990,
MSVCRT to "ANSI"(?)

> Can you explain why non-buffered I/O is better?

Depenting on the implementation, fwrite(data, sizeof(gchar), len, fp)
may really try to write <len> single-byte blocks. A large number of
buffered writes takes some time under MSVCRT, I've seen it taking
seconds (YMMV). Swapping <size> and <len> helps for now, because they
haven't implemented 2004, which mandates that the data must be written
using fputc()...

With binary I/O we have fsync(), which really flushes the data.
Even fflush() and fclose() are not guaranteed to do that.

Well, g_file_set_contents() uses buffered I/O, so obviously it's
acceptable too. But since we don't write the file line-by-line or
something, _why_ do we use buffered I/O in the first place?..

-- 
E-gards: Jimmy



More information about the Devel mailing list