OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/files/important_file_writer.h" | 5 #include "base/files/important_file_writer.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 15 matching lines...) Expand all Loading... |
26 namespace { | 26 namespace { |
27 | 27 |
28 const int kDefaultCommitIntervalMs = 10000; | 28 const int kDefaultCommitIntervalMs = 10000; |
29 | 29 |
30 enum TempFileFailure { | 30 enum TempFileFailure { |
31 FAILED_CREATING, | 31 FAILED_CREATING, |
32 FAILED_OPENING, | 32 FAILED_OPENING, |
33 FAILED_CLOSING, | 33 FAILED_CLOSING, |
34 FAILED_WRITING, | 34 FAILED_WRITING, |
35 FAILED_RENAMING, | 35 FAILED_RENAMING, |
| 36 FAILED_FLUSHING, |
36 TEMP_FILE_FAILURE_MAX | 37 TEMP_FILE_FAILURE_MAX |
37 }; | 38 }; |
38 | 39 |
39 void LogFailure(const FilePath& path, TempFileFailure failure_code, | 40 void LogFailure(const FilePath& path, TempFileFailure failure_code, |
40 const std::string& message) { | 41 const std::string& message) { |
41 UMA_HISTOGRAM_ENUMERATION("ImportantFile.TempFileFailures", failure_code, | 42 UMA_HISTOGRAM_ENUMERATION("ImportantFile.TempFileFailures", failure_code, |
42 TEMP_FILE_FAILURE_MAX); | 43 TEMP_FILE_FAILURE_MAX); |
43 DPLOG(WARNING) << "temp file failure: " << path.value().c_str() | 44 DPLOG(WARNING) << "temp file failure: " << path.value().c_str() |
44 << " : " << message; | 45 << " : " << message; |
45 } | 46 } |
(...skipping 16 matching lines...) Expand all Loading... |
62 File tmp_file(tmp_file_path, File::FLAG_OPEN | File::FLAG_WRITE); | 63 File tmp_file(tmp_file_path, File::FLAG_OPEN | File::FLAG_WRITE); |
63 if (!tmp_file.IsValid()) { | 64 if (!tmp_file.IsValid()) { |
64 LogFailure(path, FAILED_OPENING, "could not open temporary file"); | 65 LogFailure(path, FAILED_OPENING, "could not open temporary file"); |
65 return false; | 66 return false; |
66 } | 67 } |
67 | 68 |
68 // If this happens in the wild something really bad is going on. | 69 // If this happens in the wild something really bad is going on. |
69 CHECK_LE(data.length(), static_cast<size_t>(kint32max)); | 70 CHECK_LE(data.length(), static_cast<size_t>(kint32max)); |
70 int bytes_written = tmp_file.Write(0, data.data(), | 71 int bytes_written = tmp_file.Write(0, data.data(), |
71 static_cast<int>(data.length())); | 72 static_cast<int>(data.length())); |
72 tmp_file.Flush(); // Ignore return value. | 73 bool flush_success = tmp_file.Flush(); |
73 tmp_file.Close(); | 74 tmp_file.Close(); |
74 | 75 |
75 if (bytes_written < static_cast<int>(data.length())) { | 76 if (bytes_written < static_cast<int>(data.length())) { |
76 LogFailure(path, FAILED_WRITING, "error writing, bytes_written=" + | 77 LogFailure(path, FAILED_WRITING, "error writing, bytes_written=" + |
77 IntToString(bytes_written)); | 78 IntToString(bytes_written)); |
78 base::DeleteFile(tmp_file_path, false); | 79 base::DeleteFile(tmp_file_path, false); |
79 return false; | 80 return false; |
80 } | 81 } |
81 | 82 |
| 83 if (!flush_success) { |
| 84 LogFailure(path, FAILED_FLUSHING, "error flushing"); |
| 85 base::DeleteFile(tmp_file_path, false); |
| 86 return false; |
| 87 } |
| 88 |
82 if (!base::ReplaceFile(tmp_file_path, path, NULL)) { | 89 if (!base::ReplaceFile(tmp_file_path, path, NULL)) { |
83 LogFailure(path, FAILED_RENAMING, "could not rename temporary file"); | 90 LogFailure(path, FAILED_RENAMING, "could not rename temporary file"); |
84 base::DeleteFile(tmp_file_path, false); | 91 base::DeleteFile(tmp_file_path, false); |
85 return false; | 92 return false; |
86 } | 93 } |
87 | 94 |
88 return true; | 95 return true; |
89 } | 96 } |
90 | 97 |
91 ImportantFileWriter::ImportantFileWriter( | 98 ImportantFileWriter::ImportantFileWriter( |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 | 193 |
187 void ImportantFileWriter::ForwardSuccessfulWrite(bool result) { | 194 void ImportantFileWriter::ForwardSuccessfulWrite(bool result) { |
188 DCHECK(CalledOnValidThread()); | 195 DCHECK(CalledOnValidThread()); |
189 if (result && !on_next_successful_write_.is_null()) { | 196 if (result && !on_next_successful_write_.is_null()) { |
190 on_next_successful_write_.Run(); | 197 on_next_successful_write_.Run(); |
191 on_next_successful_write_.Reset(); | 198 on_next_successful_write_.Reset(); |
192 } | 199 } |
193 } | 200 } |
194 | 201 |
195 } // namespace base | 202 } // namespace base |
OLD | NEW |