OLD | NEW |
1 // Copyright 2015 The Crashpad Authors. All rights reserved. | 1 // Copyright 2015 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 PLOG(ERROR) << "mkdir"; | 82 PLOG(ERROR) << "mkdir"; |
83 return false; | 83 return false; |
84 } | 84 } |
85 } | 85 } |
86 | 86 |
87 //! \brief A CrashReportDatabase that uses HFS+ extended attributes to store | 87 //! \brief A CrashReportDatabase that uses HFS+ extended attributes to store |
88 //! report metadata. | 88 //! report metadata. |
89 //! | 89 //! |
90 //! The database maintains three directories of reports: `"new"` to hold crash | 90 //! The database maintains three directories of reports: `"new"` to hold crash |
91 //! reports that are in the process of being written, `"completed"` to hold | 91 //! reports that are in the process of being written, `"completed"` to hold |
92 //! reports that have been written and are awaing upload, and `"uploaded"` to | 92 //! reports that have been written and are awaiting upload, and `"uploaded"` to |
93 //! hold reports successfully uploaded to a collection server. If the user has | 93 //! hold reports successfully uploaded to a collection server. If the user has |
94 //! opted out of report collection, reports will still be written and moved | 94 //! opted out of report collection, reports will still be written and moved |
95 //! to the completed directory, but they just will not be uploaded. | 95 //! to the completed directory, but they just will not be uploaded. |
96 //! | 96 //! |
97 //! The database stores its metadata in extended filesystem attributes. To | 97 //! The database stores its metadata in extended filesystem attributes. To |
98 //! ensure safe access, the report file is locked using `O_EXLOCK` during all | 98 //! ensure safe access, the report file is locked using `O_EXLOCK` during all |
99 //! extended attribute operations. The lock should be obtained using | 99 //! extended attribute operations. The lock should be obtained using |
100 //! ObtainReportLock(). | 100 //! ObtainReportLock(). |
101 class CrashReportDatabaseMac : public CrashReportDatabase { | 101 class CrashReportDatabaseMac : public CrashReportDatabase { |
102 public: | 102 public: |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 //! \brief Obtains an exclusive advisory lock on a file. | 142 //! \brief Obtains an exclusive advisory lock on a file. |
143 //! | 143 //! |
144 //! The flock is used to prevent cross-process concurrent metadata reads or | 144 //! The flock is used to prevent cross-process concurrent metadata reads or |
145 //! writes. While xattrs do not observe the lock, if the lock-then-mutate | 145 //! writes. While xattrs do not observe the lock, if the lock-then-mutate |
146 //! protocol is observed by all clients of the database, it still enforces | 146 //! protocol is observed by all clients of the database, it still enforces |
147 //! synchronization. | 147 //! synchronization. |
148 //! | 148 //! |
149 //! This does not block, and so callers must ensure that the lock is valid | 149 //! This does not block, and so callers must ensure that the lock is valid |
150 //! after calling. | 150 //! after calling. |
151 //! | 151 //! |
152 //! \param[in] path The path of the file to lcok. | 152 //! \param[in] path The path of the file to lock. |
153 //! | 153 //! |
154 //! \return A scoped lock object. If the result is not valid, an error is | 154 //! \return A scoped lock object. If the result is not valid, an error is |
155 //! logged. | 155 //! logged. |
156 static base::ScopedFD ObtainReportLock(const base::FilePath& path); | 156 static base::ScopedFD ObtainReportLock(const base::FilePath& path); |
157 | 157 |
158 //! \brief Reads all the database xattrs from a file into a Report. The file | 158 //! \brief Reads all the database xattrs from a file into a Report. The file |
159 //! must be locked with ObtainReportLock. | 159 //! must be locked with ObtainReportLock. |
160 //! | 160 //! |
161 //! \param[in] path The path of the report. | 161 //! \param[in] path The path of the report. |
162 //! \param[out] report The object into which data will be read. | 162 //! \param[out] report The object into which data will be read. |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 report->upload_attempts = 0; | 478 report->upload_attempts = 0; |
479 if (ReadXattrInt(path, XattrName(kXattrUploadAttemptCount), | 479 if (ReadXattrInt(path, XattrName(kXattrUploadAttemptCount), |
480 &report->upload_attempts) == XattrStatus::kOtherError) { | 480 &report->upload_attempts) == XattrStatus::kOtherError) { |
481 return false; | 481 return false; |
482 } | 482 } |
483 | 483 |
484 return true; | 484 return true; |
485 } | 485 } |
486 | 486 |
487 // static | 487 // static |
488 CrashReportDatabase::OperationStatus | 488 CrashReportDatabase::OperationStatus CrashReportDatabaseMac::ReportsInDirectory( |
489 CrashReportDatabaseMac::ReportsInDirectory( | |
490 const base::FilePath& path, | 489 const base::FilePath& path, |
491 std::vector<const CrashReportDatabase::Report>* reports) { | 490 std::vector<const CrashReportDatabase::Report>* reports) { |
492 DCHECK(reports->empty()); | 491 DCHECK(reports->empty()); |
493 | 492 |
494 NSError* error = nil; | 493 NSError* error = nil; |
495 NSArray* paths = [[NSFileManager defaultManager] | 494 NSArray* paths = [[NSFileManager defaultManager] |
496 contentsOfDirectoryAtPath:base::SysUTF8ToNSString(path.value()) | 495 contentsOfDirectoryAtPath:base::SysUTF8ToNSString(path.value()) |
497 error:&error]; | 496 error:&error]; |
498 if (error) { | 497 if (error) { |
499 LOG(ERROR) << "Failed to enumerate reports in directory " << path.value() | 498 LOG(ERROR) << "Failed to enumerate reports in directory " << path.value() |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 const base::FilePath& path) { | 531 const base::FilePath& path) { |
533 scoped_ptr<CrashReportDatabaseMac> database_mac( | 532 scoped_ptr<CrashReportDatabaseMac> database_mac( |
534 new CrashReportDatabaseMac(path.Append(kDatabaseDirectoryName))); | 533 new CrashReportDatabaseMac(path.Append(kDatabaseDirectoryName))); |
535 if (!database_mac->Initialize()) | 534 if (!database_mac->Initialize()) |
536 database_mac.reset(); | 535 database_mac.reset(); |
537 | 536 |
538 return scoped_ptr<CrashReportDatabase>(database_mac.release()); | 537 return scoped_ptr<CrashReportDatabase>(database_mac.release()); |
539 } | 538 } |
540 | 539 |
541 } // namespace crashpad | 540 } // namespace crashpad |
OLD | NEW |