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.
This commit is contained in:
Moritz Bunkus 2017-01-07 18:48:45 +01:00
parent ab10a5d596
commit 87caecc71e
2 changed files with 18 additions and 1 deletions

View File

@ -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

View File

@ -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<mm_write_buffer_io_c &>(*s_out).discard_buffer();
s_out.reset();
}
g_cluster_helper.reset();