OLD | NEW |
1 // Copyright 2014 The Crashpad Authors. All rights reserved. | 1 // Copyright 2014 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, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 #include "util/file/file_io.h" | 15 #include "util/file/file_io.h" |
16 | 16 |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
| 18 #include "base/macros.h" |
18 #include "base/numerics/safe_conversions.h" | 19 #include "base/numerics/safe_conversions.h" |
19 | 20 |
20 namespace crashpad { | 21 namespace crashpad { |
21 | 22 |
22 bool LoggingReadFile(FileHandle file, void* buffer, size_t size) { | 23 namespace { |
23 FileOperationResult expect = base::checked_cast<FileOperationResult>(size); | 24 |
24 FileOperationResult rv = ReadFile(file, buffer, size); | 25 class FileIOReadExactly final : public internal::ReadExactlyInternal { |
25 if (rv < 0) { | 26 public: |
26 PLOG(ERROR) << "read"; | 27 explicit FileIOReadExactly(FileHandle file) |
27 return false; | 28 : ReadExactlyInternal(), file_(file) {} |
| 29 ~FileIOReadExactly() {} |
| 30 |
| 31 private: |
| 32 // ReadExactlyInternal: |
| 33 FileOperationResult Read(void* buffer, size_t size, bool can_log) override { |
| 34 FileOperationResult rv = ReadFile(file_, buffer, size); |
| 35 if (rv < 0) { |
| 36 PLOG_IF(ERROR, can_log) << internal::kNativeReadFunctionName; |
| 37 return -1; |
| 38 } |
| 39 return rv; |
28 } | 40 } |
29 if (rv != expect) { | 41 |
30 LOG(ERROR) << "read: expected " << expect << ", observed " << rv; | 42 FileHandle file_; |
| 43 |
| 44 DISALLOW_COPY_AND_ASSIGN(FileIOReadExactly); |
| 45 }; |
| 46 |
| 47 class FileIOWriteAll final : public internal::WriteAllInternal { |
| 48 public: |
| 49 explicit FileIOWriteAll(FileHandle file) : WriteAllInternal(), file_(file) {} |
| 50 ~FileIOWriteAll() {} |
| 51 |
| 52 private: |
| 53 // WriteAllInternal: |
| 54 FileOperationResult Write(const void* buffer, size_t size) override { |
| 55 return internal::NativeWriteFile(file_, buffer, size); |
| 56 } |
| 57 |
| 58 FileHandle file_; |
| 59 |
| 60 DISALLOW_COPY_AND_ASSIGN(FileIOWriteAll); |
| 61 }; |
| 62 |
| 63 } // namespace |
| 64 |
| 65 namespace internal { |
| 66 |
| 67 bool ReadExactlyInternal::ReadExactly(void* buffer, size_t size, bool can_log) { |
| 68 char* buffer_c = static_cast<char*>(buffer); |
| 69 size_t total_bytes = 0; |
| 70 size_t remaining = size; |
| 71 while (remaining > 0) { |
| 72 FileOperationResult bytes_read = Read(buffer_c, remaining, can_log); |
| 73 if (bytes_read < 0) { |
| 74 return false; |
| 75 } |
| 76 |
| 77 DCHECK_LE(static_cast<size_t>(bytes_read), remaining); |
| 78 |
| 79 if (bytes_read == 0) { |
| 80 break; |
| 81 } |
| 82 |
| 83 buffer_c += bytes_read; |
| 84 remaining -= bytes_read; |
| 85 total_bytes += bytes_read; |
| 86 } |
| 87 |
| 88 if (total_bytes != size) { |
| 89 LOG_IF(ERROR, can_log) << "ReadExactly: expected " << size << ", observed " |
| 90 << total_bytes; |
31 return false; | 91 return false; |
32 } | 92 } |
33 | 93 |
34 return true; | 94 return true; |
35 } | 95 } |
36 | 96 |
| 97 bool WriteAllInternal::WriteAll(const void* buffer, size_t size) { |
| 98 const char* buffer_c = static_cast<const char*>(buffer); |
| 99 |
| 100 while (size > 0) { |
| 101 FileOperationResult bytes_written = Write(buffer_c, size); |
| 102 if (bytes_written < 0) { |
| 103 return false; |
| 104 } |
| 105 |
| 106 DCHECK_NE(bytes_written, 0); |
| 107 |
| 108 buffer_c += bytes_written; |
| 109 size -= bytes_written; |
| 110 } |
| 111 |
| 112 return true; |
| 113 } |
| 114 |
| 115 } // namespace internal |
| 116 |
| 117 bool ReadFileExactly(FileHandle file, void* buffer, size_t size) { |
| 118 FileIOReadExactly read_exactly(file); |
| 119 return read_exactly.ReadExactly(buffer, size, false); |
| 120 } |
| 121 |
| 122 bool LoggingReadFileExactly(FileHandle file, void* buffer, size_t size) { |
| 123 FileIOReadExactly read_exactly(file); |
| 124 return read_exactly.ReadExactly(buffer, size, true); |
| 125 } |
| 126 |
| 127 bool WriteFile(FileHandle file, const void* buffer, size_t size) { |
| 128 FileIOWriteAll write_all(file); |
| 129 return write_all.WriteAll(buffer, size); |
| 130 } |
| 131 |
37 bool LoggingWriteFile(FileHandle file, const void* buffer, size_t size) { | 132 bool LoggingWriteFile(FileHandle file, const void* buffer, size_t size) { |
38 FileOperationResult expect = base::checked_cast<FileOperationResult>(size); | 133 if (!WriteFile(file, buffer, size)) { |
39 FileOperationResult rv = WriteFile(file, buffer, size); | 134 PLOG(ERROR) << internal::kNativeWriteFunctionName; |
40 if (rv < 0) { | |
41 PLOG(ERROR) << "write"; | |
42 return false; | |
43 } | |
44 if (rv != expect) { | |
45 LOG(ERROR) << "write: expected " << expect << ", observed " << rv; | |
46 return false; | 135 return false; |
47 } | 136 } |
48 | 137 |
49 return true; | 138 return true; |
50 } | 139 } |
51 | 140 |
52 void CheckedReadFile(FileHandle file, void* buffer, size_t size) { | 141 void CheckedReadFileExactly(FileHandle file, void* buffer, size_t size) { |
53 CHECK(LoggingReadFile(file, buffer, size)); | 142 CHECK(LoggingReadFileExactly(file, buffer, size)); |
54 } | 143 } |
55 | 144 |
56 void CheckedWriteFile(FileHandle file, const void* buffer, size_t size) { | 145 void CheckedWriteFile(FileHandle file, const void* buffer, size_t size) { |
57 CHECK(LoggingWriteFile(file, buffer, size)); | 146 CHECK(LoggingWriteFile(file, buffer, size)); |
58 } | 147 } |
59 | 148 |
60 void CheckedReadFileAtEOF(FileHandle file) { | 149 void CheckedReadFileAtEOF(FileHandle file) { |
61 char c; | 150 char c; |
62 FileOperationResult rv = ReadFile(file, &c, 1); | 151 FileOperationResult rv = ReadFile(file, &c, 1); |
63 if (rv < 0) { | 152 if (rv < 0) { |
64 PCHECK(rv == 0) << "read"; | 153 PCHECK(rv == 0) << internal::kNativeReadFunctionName; |
65 } else { | 154 } else { |
66 CHECK_EQ(rv, 0) << "read"; | 155 CHECK_EQ(rv, 0) << internal::kNativeReadFunctionName; |
67 } | 156 } |
68 } | 157 } |
69 | 158 |
70 void CheckedCloseFile(FileHandle file) { | 159 void CheckedCloseFile(FileHandle file) { |
71 CHECK(LoggingCloseFile(file)); | 160 CHECK(LoggingCloseFile(file)); |
72 } | 161 } |
73 | 162 |
74 } // namespace crashpad | 163 } // namespace crashpad |
OLD | NEW |