[easytag] Fix Ogg tag writing on Windows
- From: David King <davidk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [easytag] Fix Ogg tag writing on Windows
- Date: Wed, 9 Nov 2016 17:59:48 +0000 (UTC)
commit 2576fbaf7edbfdb60d25692c7c3407f36751fe68
Author: David King <amigadave amigadave com>
Date: Wed Nov 9 16:22:37 2016 +0000
Fix Ogg tag writing on Windows
Under Windows, if a file is opened for reading, it cannot be opened a
second time for writing. The Vorbis comment code keeps the file open
for reading throughout the process of writing new tags, mostly because
the audio stream must be read into memory before being written out
after the new tags. Avoid the problem by closing the input stream only
during the writing process, and at all other times maintaining a
consistent state, with the input stream open.
https://mail.gnome.org/archives/easytag-list/2016-November/msg00000.html
src/tags/vcedit.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 43 insertions(+), 4 deletions(-)
---
diff --git a/src/tags/vcedit.c b/src/tags/vcedit.c
index 536170b..cf43428 100644
--- a/src/tags/vcedit.c
+++ b/src/tags/vcedit.c
@@ -1045,19 +1045,58 @@ cleanup:
buf = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (ostream));
size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (ostream));
+ /* At least on Windows, writing to a file with an open-for-reading stream
+ * fails, so close the input stream before writing to the file. */
+ if (!g_input_stream_close (G_INPUT_STREAM (state->in), NULL, error))
+ {
+ /* Ignore the _close() failure, and try the write anyway. */
+ g_warning ("Error closing Ogg file for reading: %s",
+ (*error)->message);
+ g_clear_error (error);
+ }
+
+ g_object_unref (state->in);
+ state->in = NULL;
+
/* Write the in-memory data back out to the original file. */
if (!g_file_replace_contents (file, buf, size, NULL, FALSE,
G_FILE_CREATE_NONE, NULL, NULL, error))
{
- g_object_unref (ostream);
- g_free (buf);
- g_assert (error == NULL || *error != NULL);
- return FALSE;
+ GError *tmp_error = NULL;
+
+ g_object_unref (ostream);
+ g_free (buf);
+
+ /* Re-open the file for reading, to keep the internal state
+ * consistent. */
+ state->in = g_file_read (file, NULL, &tmp_error);
+
+ if (!state->in)
+ {
+ g_warning ("Error opening Ogg file for reading after write failure: %s",
+ tmp_error->message);
+ g_clear_error (&tmp_error);
+ g_assert (error == NULL || *error != NULL);
+ return FALSE;
+ }
+
+ g_assert (error == NULL || *error != NULL);
+ return FALSE;
}
g_free (buf);
g_object_unref (ostream);
+ /* Re-open the file, now that the write has completed. */
+ state->in = g_file_read (file, NULL, error);
+
+ if (!state->in)
+ {
+ g_assert (error == NULL || *error != NULL);
+ return FALSE;
+ }
+
+
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]