From 87caecc71e08f9d631fb9bea60f83651b5d1fe23 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Sat, 7 Jan 2017 18:48:45 +0100 Subject: [PATCH] mkvmerge cleanup: discard write buffer content in error situations This prevents the error message "not enough space on disk" being shown twice. Whenever a write fails, an exception is throw, and an appropriate error message is shown. This is the first time. Next mkvmerge goes into its cleanup routine. There it closes the output file. The output file uses a write buffer implementation. Before closing the file any outstanding buffered content is written to the disk. The disk is still full, though, triggering another exception, and another error message is output. The workaround is to discard any buffered content still remaining at cleanup time. This is safe as the output file is closed manually normal program flow. Therefore no buffered content is lost in a successful run. Fixes #1850. --- NEWS.md | 2 ++ src/merge/output_control.cpp | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 56617d32b..e915f6f21 100644 --- a/NEWS.md +++ b/NEWS.md @@ -14,6 +14,8 @@ ## Bug fixes +* mkvmerge: fixed that the error message "not enough space on disk" was shown + twice on some operating systems. Fixes #1850. * mkvmerge, Matroska: if a codec delay is set for a track in the input file, it is kept. Fixes #1849. * GUI: multiplexer: changing default values in the prerefences (e.g. the diff --git a/src/merge/output_control.cpp b/src/merge/output_control.cpp index 8d20536ea..4600d3db1 100644 --- a/src/merge/output_control.cpp +++ b/src/merge/output_control.cpp @@ -264,6 +264,10 @@ sighandler(int /* signum */) { mxinfo(Y(" done\n")); + // Manually close s_out because cleanup() will discard any remaining + // write buffer content in s_out. + s_out->close(); + cleanup(); mxerror(Y("mkvmerge was interrupted by a SIGINT (Ctrl+C?)\n")); @@ -2090,7 +2094,18 @@ destroy_readers() { */ void cleanup() { - s_out.reset(); + if (s_out) { + // If cleanup was called as a result of an exception during + // writing due to the file system being full, the destructor would + // normally write remaining buffered before closing the file. This + // would lead to another exception and another error + // message. However, the regular paths all close the file + // manually. Therefore any buffered content remaining at this + // point can only be due to an error having occurred. The content + // can therefore be discarded. + dynamic_cast(*s_out).discard_buffer(); + s_out.reset(); + } g_cluster_helper.reset();