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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 //! \brief Obtains an exclusive advisory lock on a file. | 143 //! \brief Obtains an exclusive advisory lock on a file. |
144 //! | 144 //! |
145 //! The flock is used to prevent cross-process concurrent metadata reads or | 145 //! The flock is used to prevent cross-process concurrent metadata reads or |
146 //! writes. While xattrs do not observe the lock, if the lock-then-mutate | 146 //! writes. While xattrs do not observe the lock, if the lock-then-mutate |
147 //! protocol is observed by all clients of the database, it still enforces | 147 //! protocol is observed by all clients of the database, it still enforces |
148 //! synchronization. | 148 //! synchronization. |
149 //! | 149 //! |
150 //! This does not block, and so callers must ensure that the lock is valid | 150 //! This does not block, and so callers must ensure that the lock is valid |
151 //! after calling. | 151 //! after calling. |
152 //! | 152 //! |
153 //! \param[in] path The path of the file to lcok. | 153 //! \param[in] path The path of the file to lock. |
154 //! | 154 //! |
155 //! \return A scoped lock object. If the result is not valid, an error is | 155 //! \return A scoped lock object. If the result is not valid, an error is |
156 //! logged. | 156 //! logged. |
157 static base::ScopedFD ObtainReportLock(const base::FilePath& path); | 157 static base::ScopedFD ObtainReportLock(const base::FilePath& path); |
158 | 158 |
159 //! \brief Reads all the database xattrs from a file into a Report. The file | 159 //! \brief Reads all the database xattrs from a file into a Report. The file |
160 //! must be locked with ObtainReportLock. | 160 //! must be locked with ObtainReportLock. |
161 //! | 161 //! |
162 //! \param[in] path The path of the report. | 162 //! \param[in] path The path of the report. |
163 //! \param[out] report The object into which data will be read. | 163 //! \param[out] report The object into which data will be read. |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 report->upload_attempts = 0; | 497 report->upload_attempts = 0; |
498 if (ReadXattrInt(path, XattrName(kXattrUploadAttemptCount), | 498 if (ReadXattrInt(path, XattrName(kXattrUploadAttemptCount), |
499 &report->upload_attempts) == XattrStatus::kOtherError) { | 499 &report->upload_attempts) == XattrStatus::kOtherError) { |
500 return false; | 500 return false; |
501 } | 501 } |
502 | 502 |
503 return true; | 503 return true; |
504 } | 504 } |
505 | 505 |
506 // static | 506 // static |
507 CrashReportDatabase::OperationStatus | 507 CrashReportDatabase::OperationStatus CrashReportDatabaseMac::ReportsInDirectory( |
508 CrashReportDatabaseMac::ReportsInDirectory( | |
509 const base::FilePath& path, | 508 const base::FilePath& path, |
510 std::vector<const CrashReportDatabase::Report>* reports) { | 509 std::vector<const CrashReportDatabase::Report>* reports) { |
511 DCHECK(reports->empty()); | 510 DCHECK(reports->empty()); |
512 | 511 |
513 NSError* error = nil; | 512 NSError* error = nil; |
514 NSArray* paths = [[NSFileManager defaultManager] | 513 NSArray* paths = [[NSFileManager defaultManager] |
515 contentsOfDirectoryAtPath:base::SysUTF8ToNSString(path.value()) | 514 contentsOfDirectoryAtPath:base::SysUTF8ToNSString(path.value()) |
516 error:&error]; | 515 error:&error]; |
517 if (error) { | 516 if (error) { |
518 LOG(ERROR) << "Failed to enumerate reports in directory " << path.value() | 517 LOG(ERROR) << "Failed to enumerate reports in directory " << path.value() |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 const base::FilePath& path) { | 550 const base::FilePath& path) { |
552 scoped_ptr<CrashReportDatabaseMac> database_mac( | 551 scoped_ptr<CrashReportDatabaseMac> database_mac( |
553 new CrashReportDatabaseMac(path.Append(kDatabaseDirectoryName))); | 552 new CrashReportDatabaseMac(path.Append(kDatabaseDirectoryName))); |
554 if (!database_mac->Initialize()) | 553 if (!database_mac->Initialize()) |
555 database_mac.reset(); | 554 database_mac.reset(); |
556 | 555 |
557 return scoped_ptr<CrashReportDatabase>(database_mac.release()); | 556 return scoped_ptr<CrashReportDatabase>(database_mac.release()); |
558 } | 557 } |
559 | 558 |
560 } // namespace crashpad | 559 } // namespace crashpad |
OLD | NEW |