| 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 |