diff --git a/src/processor/disk_module_cache.cc b/src/processor/disk_module_cache.cc index 6792a5da..50437ee3 100644 --- a/src/processor/disk_module_cache.cc +++ b/src/processor/disk_module_cache.cc @@ -30,9 +30,13 @@ #include #include #include +#include +#include +#include #include #include +#include #include "processor/disk_module_cache.h" #include "processor/logging.h" @@ -43,10 +47,43 @@ using std::ofstream; using std::istream; using std::ifstream; using std::ios; +using std::vector; namespace google_breakpad { +// tempofstream writes data to a temporary file in the same +// directory as the file passed to the constructor. +// when closed, it renames the temporary file to the given filename. +class tempofstream : public ofstream +{ +public: + tempofstream(const char * filename, ios_base::openmode mode = ios_base::out); + void close(); + +private: + string tempname_; + string filename_; +}; + +tempofstream::tempofstream(const char * filename, + ios_base::openmode mode) : tempname_(""), + filename_(filename) +{ + string name_template_s = filename_ + "XXXXXX"; + vector name_template(name_template_s.length()); + std::copy(name_template_s.begin(), name_template_s.end(), + name_template.begin()); + tempname_ = mktemp(&name_template[0]); + open(tempname_.c_str(), mode); +} + +void tempofstream::close() +{ + ofstream::close(); + rename(tempname_.c_str(), filename_.c_str()); +} + DiskModuleCache::DiskModuleCache(string cache_directory) : cache_directory_(cache_directory) { @@ -88,8 +125,8 @@ bool DiskModuleCache::BeginSetModuleData(const string &symbol_file, if (!EnsurePathExists(cache_file.substr(0, cache_file.rfind('/')))) return false; - *data_stream = new ofstream(cache_file.c_str(), - ios::out | ios::binary | ios::trunc); + *data_stream = new tempofstream(cache_file.c_str(), + ios::out | ios::binary | ios::trunc); if (!**data_stream) { delete *data_stream; *data_stream = NULL; @@ -101,7 +138,7 @@ bool DiskModuleCache::BeginSetModuleData(const string &symbol_file, bool DiskModuleCache::EndSetModuleData(const string &symbol_file, ostream **data_stream) { - ofstream *file_stream = dynamic_cast(*data_stream); + tempofstream *file_stream = dynamic_cast(*data_stream); if (!file_stream) return false; diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index f7bc7f31..3e48b1e2 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -36,6 +36,7 @@ #include #include +#include #include #include #ifdef _WIN32 diff --git a/src/processor/simple_symbol_supplier.cc b/src/processor/simple_symbol_supplier.cc index df61e849..291361cb 100644 --- a/src/processor/simple_symbol_supplier.cc +++ b/src/processor/simple_symbol_supplier.cc @@ -36,6 +36,7 @@ #include #include +#include #include #include "processor/simple_symbol_supplier.h"