Repository: bitcoin/bitcoin
File: src/addrdb.cpp (C++)

Code before:
    // open temp output file
    fs::path pathTmp = gArgs.GetDataDirNet() / fs::u8path(tmpfn);
    FILE *file = fsbridge::fopen(pathTmp, "wb");
    AutoFile fileout{file};
    if (fileout.IsNull()) {
        fileout.fclose();
        remove(pathTmp);
        LogError("%s: Failed to open file %s\n", __func__, fs::PathToString(pathTmp));
        return false;
    }

    // Serialize
    if (!SerializeDB(fileout, data)) {
        fileout.fclose();
        remove(pathTmp);
        return false;
    }
    if (!fileout.Commit()) {
        fileout.fclose();
        remove(pathTmp);
        LogError("%s: Failed to flush file %s\n", __func__, fs::PathToString(pathTmp));
        return false;
    }
    fileout.fclose();

    // replace existing file, if any, with new file
    if (!RenameOver(pathTmp, path)) {
        remove(pathTmp);
        LogError("%s: Rename-into-place failed\n", __func__);
        return false;
    }

    return true;
}

template <typename Stream, typename Data>
void DeserializeDB(Stream& stream, Data&& data, bool fCheckSum = true)
{
    HashVerifier verifier{stream};
    // de-serialize file header (network specific magic number) and ..
    MessageStartChars pchMsgTmp;
    verifier >> pchMsgTmp;
    // ... verify the network matches ours
    if (pchMsgTmp != Params().MessageStart()) {
        throw std::runtime_error{"Invalid network magic number"};
    }

    // de-serialize data
    verifier >> data;

    // verify checksum

Review comment (bug):
Less error-prone to use the error value returned from `fclose()` rather than relying on global `errno` which might have been mutated by `remove()` etc.
```suggestion
    if (int err{fileout.fclose()}; err != 0) {
        remove(pathTmp);
        LogError("Failed to close file %s: %s", fs::PathToString(pathTmp), SysErrorString(err));
```
(Also dropped pre-`-logsourcelocations` `__func__` and removed superfluous newline).

Code after:

    // open temp output file
    fs::path pathTmp = gArgs.GetDataDirNet() / fs::u8path(tmpfn);
    FILE *file = fsbridge::fopen(pathTmp, "wb");
    AutoFile fileout{file};
    if (fileout.IsNull()) {
        remove(pathTmp);
        LogError("%s: Failed to open file %s\n", __func__, fs::PathToString(pathTmp));
        return false;
    }

    // Serialize
    if (!SerializeDB(fileout, data)) {
        (void)fileout.fclose();
        remove(pathTmp);
        return false;
    }
    if (!fileout.Commit()) {
        (void)fileout.fclose();
        remove(pathTmp);
        LogError("%s: Failed to flush file %s\n", __func__, fs::PathToString(pathTmp));
        return false;
    }
    if (fileout.fclose() != 0) {
        const int errno_save{errno};
        remove(pathTmp);
        LogError("Failed to close file %s after commit: %s", fs::PathToString(pathTmp), SysErrorString(errno_save));
        return false;
    }

    // replace existing file, if any, with new file
    if (!RenameOver(pathTmp, path)) {
        remove(pathTmp);
        LogError("%s: Rename-into-place failed\n", __func__);
        return false;
    }

    return true;
}

template <typename Stream, typename Data>
void DeserializeDB(Stream& stream, Data&& data, bool fCheckSum = true)
{
    HashVerifier verifier{stream};
    // de-serialize file header (network specific magic number) and ..
    MessageStartChars pchMsgTmp;
    verifier >> pchMsgTmp;
    // ... verify the network matches ours
    if (pchMsgTmp != Params().MessageStart()) {
        throw std::runtime_error{"Invalid network magic number"};
    }