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, |
(...skipping 19 matching lines...) Expand all Loading... |
30 | 30 |
31 #if defined(OS_POSIX) | 31 #if defined(OS_POSIX) |
32 // Ensure type compatibility between WritableIoVec and iovec. | 32 // Ensure type compatibility between WritableIoVec and iovec. |
33 static_assert(sizeof(WritableIoVec) == sizeof(iovec), "WritableIoVec size"); | 33 static_assert(sizeof(WritableIoVec) == sizeof(iovec), "WritableIoVec size"); |
34 static_assert(offsetof(WritableIoVec, iov_base) == offsetof(iovec, iov_base), | 34 static_assert(offsetof(WritableIoVec, iov_base) == offsetof(iovec, iov_base), |
35 "WritableIoVec base offset"); | 35 "WritableIoVec base offset"); |
36 static_assert(offsetof(WritableIoVec, iov_len) == offsetof(iovec, iov_len), | 36 static_assert(offsetof(WritableIoVec, iov_len) == offsetof(iovec, iov_len), |
37 "WritableIoVec len offset"); | 37 "WritableIoVec len offset"); |
38 #endif // OS_POSIX | 38 #endif // OS_POSIX |
39 | 39 |
40 FileWriter::FileWriter() : file_() { | 40 WeakFileHandleFileWriter::WeakFileHandleFileWriter(FileHandle file_handle) |
| 41 : file_handle_(file_handle) { |
41 } | 42 } |
42 | 43 |
43 FileWriter::~FileWriter() { | 44 WeakFileHandleFileWriter::~WeakFileHandleFileWriter() { |
44 } | 45 } |
45 | 46 |
46 bool FileWriter::Open(const base::FilePath& path, | 47 bool WeakFileHandleFileWriter::Write(const void* data, size_t size) { |
47 FileWriteMode write_mode, | 48 DCHECK_NE(file_handle_, kInvalidFileHandle); |
48 FilePermissions permissions) { | |
49 CHECK(!file_.is_valid()); | |
50 file_.reset(LoggingOpenFileForWrite(path, write_mode, permissions)); | |
51 return file_.is_valid(); | |
52 } | |
53 | |
54 void FileWriter::Close() { | |
55 CHECK(file_.is_valid()); | |
56 | |
57 file_.reset(); | |
58 } | |
59 | |
60 bool FileWriter::Write(const void* data, size_t size) { | |
61 DCHECK(file_.is_valid()); | |
62 | 49 |
63 // TODO(mark): Write no more than SSIZE_MAX bytes in a single call. | 50 // TODO(mark): Write no more than SSIZE_MAX bytes in a single call. |
64 ssize_t written = WriteFile(file_.get(), data, size); | 51 ssize_t written = WriteFile(file_handle_, data, size); |
65 if (written < 0) { | 52 if (written < 0) { |
66 PLOG(ERROR) << "write"; | 53 PLOG(ERROR) << "write"; |
67 return false; | 54 return false; |
68 } else if (written == 0) { | 55 } else if (written == 0) { |
69 LOG(ERROR) << "write: returned 0"; | 56 LOG(ERROR) << "write: returned 0"; |
70 return false; | 57 return false; |
71 } | 58 } |
72 | 59 |
73 return true; | 60 return true; |
74 } | 61 } |
75 | 62 |
76 bool FileWriter::WriteIoVec(std::vector<WritableIoVec>* iovecs) { | 63 bool WeakFileHandleFileWriter::WriteIoVec(std::vector<WritableIoVec>* iovecs) { |
77 DCHECK(file_.is_valid()); | 64 DCHECK_NE(file_handle_, kInvalidFileHandle); |
78 | 65 |
79 #if defined(OS_POSIX) | 66 #if defined(OS_POSIX) |
80 | 67 |
81 ssize_t size = 0; | 68 ssize_t size = 0; |
82 for (const WritableIoVec& iov : *iovecs) { | 69 for (const WritableIoVec& iov : *iovecs) { |
83 // TODO(mark): Check to avoid overflow of ssize_t, and fail with EINVAL. | 70 // TODO(mark): Check to avoid overflow of ssize_t, and fail with EINVAL. |
84 size += iov.iov_len; | 71 size += iov.iov_len; |
85 } | 72 } |
86 | 73 |
87 // Get an iovec*, because that’s what writev wants. The only difference | 74 // Get an iovec*, because that’s what writev wants. The only difference |
88 // between WritableIoVec and iovec is that WritableIoVec’s iov_base is a | 75 // between WritableIoVec and iovec is that WritableIoVec’s iov_base is a |
89 // pointer to a const buffer, where iovec’s iov_base isn’t. writev doesn’t | 76 // pointer to a const buffer, where iovec’s iov_base isn’t. writev doesn’t |
90 // actually write to the data, so this cast is safe here. iovec’s iov_base is | 77 // actually write to the data, so this cast is safe here. iovec’s iov_base is |
91 // non-const because the same structure is used for readv and writev, and | 78 // non-const because the same structure is used for readv and writev, and |
92 // readv needs to write to the buffer that iov_base points to. | 79 // readv needs to write to the buffer that iov_base points to. |
93 iovec* iov = reinterpret_cast<iovec*>(&(*iovecs)[0]); | 80 iovec* iov = reinterpret_cast<iovec*>(&(*iovecs)[0]); |
94 size_t remaining_iovecs = iovecs->size(); | 81 size_t remaining_iovecs = iovecs->size(); |
95 | 82 |
96 while (size > 0) { | 83 while (size > 0) { |
97 size_t writev_iovec_count = | 84 size_t writev_iovec_count = |
98 std::min(remaining_iovecs, implicit_cast<size_t>(IOV_MAX)); | 85 std::min(remaining_iovecs, implicit_cast<size_t>(IOV_MAX)); |
99 ssize_t written = | 86 ssize_t written = |
100 HANDLE_EINTR(writev(file_.get(), iov, writev_iovec_count)); | 87 HANDLE_EINTR(writev(file_handle_, iov, writev_iovec_count)); |
101 if (written < 0) { | 88 if (written < 0) { |
102 PLOG(ERROR) << "writev"; | 89 PLOG(ERROR) << "writev"; |
103 return false; | 90 return false; |
104 } else if (written == 0) { | 91 } else if (written == 0) { |
105 LOG(ERROR) << "writev: returned 0"; | 92 LOG(ERROR) << "writev: returned 0"; |
106 return false; | 93 return false; |
107 } | 94 } |
108 | 95 |
109 size -= written; | 96 size -= written; |
110 DCHECK_GE(size, 0); | 97 DCHECK_GE(size, 0); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 | 129 |
143 #ifndef NDEBUG | 130 #ifndef NDEBUG |
144 // The interface says that |iovecs| is not sacred, so scramble it to make sure | 131 // The interface says that |iovecs| is not sacred, so scramble it to make sure |
145 // that nobody depends on it. | 132 // that nobody depends on it. |
146 memset(&(*iovecs)[0], 0xa5, sizeof((*iovecs)[0]) * iovecs->size()); | 133 memset(&(*iovecs)[0], 0xa5, sizeof((*iovecs)[0]) * iovecs->size()); |
147 #endif | 134 #endif |
148 | 135 |
149 return true; | 136 return true; |
150 } | 137 } |
151 | 138 |
| 139 FileOffset WeakFileHandleFileWriter::Seek(FileOffset offset, int whence) { |
| 140 DCHECK_NE(file_handle_, kInvalidFileHandle); |
| 141 return LoggingSeekFile(file_handle_, offset, whence); |
| 142 } |
| 143 |
| 144 FileWriter::FileWriter() |
| 145 : file_(), |
| 146 weak_file_handle_file_writer_(kInvalidFileHandle) { |
| 147 } |
| 148 |
| 149 FileWriter::~FileWriter() { |
| 150 } |
| 151 |
| 152 bool FileWriter::Open(const base::FilePath& path, |
| 153 FileWriteMode write_mode, |
| 154 FilePermissions permissions) { |
| 155 CHECK(!file_.is_valid()); |
| 156 file_.reset(LoggingOpenFileForWrite(path, write_mode, permissions)); |
| 157 if (!file_.is_valid()) { |
| 158 return false; |
| 159 } |
| 160 |
| 161 weak_file_handle_file_writer_.set_file_handle(file_.get()); |
| 162 return true; |
| 163 } |
| 164 |
| 165 void FileWriter::Close() { |
| 166 CHECK(file_.is_valid()); |
| 167 |
| 168 weak_file_handle_file_writer_.set_file_handle(kInvalidFileHandle); |
| 169 file_.reset(); |
| 170 } |
| 171 |
| 172 bool FileWriter::Write(const void* data, size_t size) { |
| 173 DCHECK(file_.is_valid()); |
| 174 return weak_file_handle_file_writer_.Write(data, size); |
| 175 } |
| 176 |
| 177 bool FileWriter::WriteIoVec(std::vector<WritableIoVec>* iovecs) { |
| 178 DCHECK(file_.is_valid()); |
| 179 return weak_file_handle_file_writer_.WriteIoVec(iovecs); |
| 180 } |
| 181 |
152 FileOffset FileWriter::Seek(FileOffset offset, int whence) { | 182 FileOffset FileWriter::Seek(FileOffset offset, int whence) { |
153 DCHECK(file_.is_valid()); | 183 DCHECK(file_.is_valid()); |
154 return LoggingSeekFile(file_.get(), offset, whence); | 184 return weak_file_handle_file_writer_.Seek(offset, whence); |
155 } | 185 } |
156 | 186 |
157 } // namespace crashpad | 187 } // namespace crashpad |
OLD | NEW |