mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-19 23:03:45 +01:00
Explicitly close all AutoFiles that have been written
There is no way to report a close error from `AutoFile` destructor. Such an error could be serious if the file has been written to because it may mean the file is now corrupted (same as if write fails). So, change all users of `AutoFile` that use it to write data to explicitly close the file and handle a possible error.
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
#include <util/fs.h>
|
||||
#include <util/signalinterrupt.h>
|
||||
#include <util/strencodings.h>
|
||||
#include <util/syserror.h>
|
||||
#include <util/translation.h>
|
||||
#include <validation.h>
|
||||
|
||||
@@ -941,13 +942,13 @@ bool BlockManager::WriteBlockUndo(const CBlockUndo& blockundo, BlockValidationSt
|
||||
return false;
|
||||
}
|
||||
|
||||
// Open history file to append
|
||||
AutoFile file{OpenUndoFile(pos)};
|
||||
if (file.IsNull()) {
|
||||
LogError("OpenUndoFile failed for %s while writing block undo", pos.ToString());
|
||||
return FatalError(m_opts.notifications, state, _("Failed to write undo data."));
|
||||
}
|
||||
{
|
||||
// Open history file to append
|
||||
AutoFile file{OpenUndoFile(pos)};
|
||||
if (file.IsNull()) {
|
||||
LogError("OpenUndoFile failed for %s while writing block undo", pos.ToString());
|
||||
return FatalError(m_opts.notifications, state, _("Failed to write undo data."));
|
||||
}
|
||||
BufferedWriter fileout{file};
|
||||
|
||||
// Write index header
|
||||
@@ -960,8 +961,13 @@ bool BlockManager::WriteBlockUndo(const CBlockUndo& blockundo, BlockValidationSt
|
||||
// Write undo data & checksum
|
||||
fileout << blockundo << hasher.GetHash();
|
||||
}
|
||||
// BufferedWriter will flush pending data to file when fileout goes out of scope.
|
||||
}
|
||||
|
||||
fileout.flush(); // Make sure `AutoFile`/`BufferedWriter` go out of scope before we call `FlushUndoFile`
|
||||
// Make sure that the file is closed before we call `FlushUndoFile`.
|
||||
if (file.fclose() != 0) {
|
||||
LogError("Failed to close block undo file %s: %s", pos.ToString(), SysErrorString(errno));
|
||||
return FatalError(m_opts.notifications, state, _("Failed to close block undo file."));
|
||||
}
|
||||
|
||||
// rev files are written in block height order, whereas blk files are written as blocks come in (often out of order)
|
||||
@@ -1094,13 +1100,22 @@ FlatFilePos BlockManager::WriteBlock(const CBlock& block, int nHeight)
|
||||
m_opts.notifications.fatalError(_("Failed to write block."));
|
||||
return FlatFilePos();
|
||||
}
|
||||
BufferedWriter fileout{file};
|
||||
{
|
||||
BufferedWriter fileout{file};
|
||||
|
||||
// Write index header
|
||||
fileout << GetParams().MessageStart() << block_size;
|
||||
pos.nPos += STORAGE_HEADER_BYTES;
|
||||
// Write block
|
||||
fileout << TX_WITH_WITNESS(block);
|
||||
}
|
||||
|
||||
if (file.fclose() != 0) {
|
||||
LogError("Failed to close block file %s: %s", pos.ToString(), SysErrorString(errno));
|
||||
m_opts.notifications.fatalError(_("Failed to close file when writing block."));
|
||||
return FlatFilePos();
|
||||
}
|
||||
|
||||
// Write index header
|
||||
fileout << GetParams().MessageStart() << block_size;
|
||||
pos.nPos += STORAGE_HEADER_BYTES;
|
||||
// Write block
|
||||
fileout << TX_WITH_WITNESS(block);
|
||||
return pos;
|
||||
}
|
||||
|
||||
@@ -1143,6 +1158,11 @@ static auto InitBlocksdirXorKey(const BlockManager::Options& opts)
|
||||
#endif
|
||||
)};
|
||||
xor_key_file << xor_key;
|
||||
if (xor_key_file.fclose() != 0) {
|
||||
throw std::runtime_error{strprintf("Error closing XOR key file %s: %s",
|
||||
fs::PathToString(xor_key_path),
|
||||
SysErrorString(errno))};
|
||||
}
|
||||
}
|
||||
// If the user disabled the key, it must be zero.
|
||||
if (!opts.use_xor && xor_key != decltype(xor_key){}) {
|
||||
|
||||
Reference in New Issue
Block a user