Index: client/settings.cc |
diff --git a/client/settings.cc b/client/settings.cc |
index aa2c4f8f21ac9d52ab5c78de9fb6467a9e97d174..d1b35f1a7d6a3e5b196157bfdba3b64e7dd46fa4 100644 |
--- a/client/settings.cc |
+++ b/client/settings.cc |
@@ -16,10 +16,6 @@ |
#include <limits> |
-#include <fcntl.h> |
-#include <unistd.h> |
-#include <uuid/uuid.h> |
- |
#include "base/compiler_specific.h" |
#include "base/logging.h" |
#include "base/posix/eintr_wrapper.h" |
@@ -27,6 +23,23 @@ |
namespace crashpad { |
+namespace internal { |
+ |
+// static |
+FileHandle ScopedLockedFileHandleTraits::InvalidValue() { |
+ return kInvalidFileHandle; |
+} |
+ |
+// static |
+void ScopedLockedFileHandleTraits::Free(FileHandle handle) { |
+ if (handle != kInvalidFileHandle) { |
+ LoggingUnlockFile(handle); |
+ CheckedCloseFile(handle); |
+ } |
+} |
+ |
+} // namespace internal |
+ |
struct ALIGNAS(4) Settings::Data { |
static const uint32_t kSettingsMagic = 'CPds'; |
static const uint32_t kSettingsVersion = 1; |
@@ -61,23 +74,6 @@ Settings::~Settings() { |
bool Settings::Initialize() { |
INITIALIZATION_STATE_SET_INITIALIZING(initialized_); |
- ScopedFileHandle handle(HANDLE_EINTR( |
- open(file_path().value().c_str(), |
- O_CREAT | O_EXCL | O_WRONLY | O_EXLOCK, |
- 0644))); |
- |
- // The file was created, so this is a new database that needs to be |
- // initialized with a client ID. |
- if (handle.is_valid()) { |
- bool initialized = InitializeSettings(handle.get()); |
- if (initialized) |
- INITIALIZATION_STATE_SET_VALID(initialized_); |
- return initialized; |
- } |
- |
- // The file wasn't created, try opening it for a write operation. If the file |
- // needs to be recovered, writing is necessary. This also ensures that the |
- // process has permission to write the file. |
Data settings; |
if (!OpenForWritingAndReadSettings(&settings).is_valid()) |
return false; |
@@ -112,7 +108,7 @@ bool Settings::SetUploadsEnabled(bool enabled) { |
INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
Data settings; |
- ScopedFileHandle handle = OpenForWritingAndReadSettings(&settings); |
+ ScopedLockedFileHandle handle = OpenForWritingAndReadSettings(&settings); |
if (!handle.is_valid()) |
return false; |
@@ -140,7 +136,7 @@ bool Settings::SetLastUploadAttemptTime(time_t time) { |
INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
Data settings; |
- ScopedFileHandle handle = OpenForWritingAndReadSettings(&settings); |
+ ScopedLockedFileHandle handle = OpenForWritingAndReadSettings(&settings); |
if (!handle.is_valid()) |
return false; |
@@ -149,22 +145,33 @@ bool Settings::SetLastUploadAttemptTime(time_t time) { |
return WriteSettings(handle.get(), settings); |
} |
-ScopedFileHandle Settings::OpenForReading() { |
- ScopedFileHandle handle(HANDLE_EINTR( |
- open(file_path().value().c_str(), O_RDONLY | O_SHLOCK))); |
- PLOG_IF(ERROR, !handle.is_valid()) << "open for reading"; |
- return handle.Pass(); |
+// static |
+Settings::ScopedLockedFileHandle Settings::MakeScopedLockedFileHandle( |
+ FileHandle file, |
+ FileLocking locking) { |
+ ScopedFileHandle scoped(file); |
+ if (scoped.is_valid()) { |
+ if (!LoggingLockFile(scoped.get(), locking)) |
+ scoped.reset(); |
+ } |
+ return ScopedLockedFileHandle(scoped.release()); |
} |
-ScopedFileHandle Settings::OpenForReadingAndWriting() { |
- ScopedFileHandle handle(HANDLE_EINTR( |
- open(file_path().value().c_str(), O_RDWR | O_EXLOCK | O_CREAT, 0644))); |
- PLOG_IF(ERROR, !handle.is_valid()) << "open for writing"; |
- return handle.Pass(); |
+Settings::ScopedLockedFileHandle Settings::OpenForReading() { |
+ return MakeScopedLockedFileHandle(LoggingOpenFileForRead(file_path()), |
+ FileLocking::kShared); |
+} |
+ |
+Settings::ScopedLockedFileHandle Settings::OpenForReadingAndWriting() { |
+ return MakeScopedLockedFileHandle( |
+ LoggingOpenFileForReadAndWrite(file_path(), |
+ FileWriteMode::kReuseOrCreate, |
+ FilePermissions::kWorldReadable), |
+ FileLocking::kExclusive); |
} |
bool Settings::OpenAndReadSettings(Data* out_data) { |
- ScopedFileHandle handle = OpenForReading(); |
+ ScopedLockedFileHandle handle = OpenForReading(); |
if (!handle.is_valid()) |
return false; |
@@ -178,14 +185,15 @@ bool Settings::OpenAndReadSettings(Data* out_data) { |
return RecoverSettings(kInvalidFileHandle, out_data); |
} |
-ScopedFileHandle Settings::OpenForWritingAndReadSettings(Data* out_data) { |
- ScopedFileHandle handle = OpenForReadingAndWriting(); |
+Settings::ScopedLockedFileHandle Settings::OpenForWritingAndReadSettings( |
+ Data* out_data) { |
+ ScopedLockedFileHandle handle = OpenForReadingAndWriting(); |
if (!handle.is_valid()) |
- return ScopedFileHandle(); |
+ return ScopedLockedFileHandle(); |
if (!ReadSettings(handle.get(), out_data)) { |
if (!RecoverSettings(handle.get(), out_data)) |
- return ScopedFileHandle(); |
+ return ScopedLockedFileHandle(); |
} |
return handle.Pass(); |
@@ -215,16 +223,14 @@ bool Settings::WriteSettings(FileHandle handle, const Data& data) { |
if (LoggingSeekFile(handle, 0, SEEK_SET) != 0) |
return false; |
- if (HANDLE_EINTR(ftruncate(handle, 0)) != 0) { |
- PLOG(ERROR) << "ftruncate settings file"; |
+ if (!LoggingTruncateFile(handle)) |
return false; |
- } |
return LoggingWriteFile(handle, &data, sizeof(Data)); |
} |
bool Settings::RecoverSettings(FileHandle handle, Data* out_data) { |
- ScopedFileHandle scoped_handle; |
+ ScopedLockedFileHandle scoped_handle; |
if (handle == kInvalidFileHandle) { |
scoped_handle = OpenForReadingAndWriting(); |
handle = scoped_handle.get(); |
@@ -235,8 +241,6 @@ bool Settings::RecoverSettings(FileHandle handle, Data* out_data) { |
return true; |
} |
- LOG(INFO) << "Recovering settings file " << file_path().value(); |
- |
if (handle == kInvalidFileHandle) { |
LOG(ERROR) << "Invalid file handle"; |
return false; |
@@ -249,11 +253,9 @@ bool Settings::RecoverSettings(FileHandle handle, Data* out_data) { |
} |
bool Settings::InitializeSettings(FileHandle handle) { |
- uuid_t uuid; |
- uuid_generate(uuid); |
- |
Data settings; |
- settings.client_id.InitializeFromBytes(uuid); |
+ if (!settings.client_id.InitializeWithNew()) |
+ return false; |
return WriteSettings(handle, settings); |
} |