diff options
author | Will Thompson <wjt@endlessm.com> | 2017-11-22 11:43:55 +0000 |
---|---|---|
committer | Will Thompson <will@willthompson.co.uk> | 2018-06-15 14:47:47 +0100 |
commit | c1a8e93dc42122383483ef9d9ed748e9330dd2ec (patch) | |
tree | 577ad7fe944d3e0922b4e538bfaf89c7251f605b | |
parent | acb4f5483328d0f2dd3adf31628209ffeac8efdf (diff) | |
download | glib-non-atomicity-of-g_file_set_contents.tar.gz |
gfileutils: document non-atomicity of g_file_set_contents()non-atomicity-of-g_file_set_contents
This function only calls fsync() if @target exists and is non-empty. If
not, it doesn't provide the "old contents or new contents" guarantee
that one might expect. This has been the case since
d20a188b1250ab3cf211d684429127d99378e886, and is justified either as a
performance optimization or by asserting that this function only
guarantees to not destroy existing data (implicitly defining
non-existence or emptiness as not data).
In addition, explicitly spell out that whether it's atomic in the
non-empty case is system-dependent. If the system administrator has
configured some funky filesystem options, they may be out of luck on the
atomicity front.
https://gitlab.gnome.org/GNOME/glib/issues/1302
-rw-r--r-- | glib/gfileutils.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/glib/gfileutils.c b/glib/gfileutils.c index 380c8d147..1e7a771a9 100644 --- a/glib/gfileutils.c +++ b/glib/gfileutils.c @@ -1173,6 +1173,17 @@ write_to_temp_file (const gchar *contents, * lists, metadata etc. may be lost. If @filename is a symbolic link, * the link itself will be replaced, not the linked file. * + * - On UNIX, if @filename already exists and is non-empty, and if the system + * supports it (via a journalling filesystem or equivalent), the fsync() + * call (or equivalent) will be used to ensure atomic replacement: @filename + * will contain either its old contents or @contents, even in the face of + * system power loss, the disk being unsafely removed, etc. + * + * - On UNIX, if @filename does not already exist or is empty, there is a + * possibility that system power loss etc. after calling this function will + * leave @filename empty or full of NUL bytes, depending on the underlying + * filesystem. + * * - On Windows renaming a file will not remove an existing file with the * new name, so on Windows there is a race condition between the existing * file being removed and the temporary file being renamed. |