diff options
author | Adam Lesinski | 2017-07-25 17:22:21 -0500 |
---|---|---|
committer | Gerrit Code Review | 2017-07-25 17:22:21 -0500 |
commit | a0360ad6a365b625da039b16e9b9b55ab2425afe (patch) | |
tree | d5a0aa2ddecec16d9a4a9a6f3555660093fa8dea /base | |
parent | 80ec81cf4b9f4e9a529df618ea38a3f995a2f249 (diff) | |
parent | de117e4a49d6ed047c0c1a9270be5d8a191aa2db (diff) | |
download | platform-system-core-a0360ad6a365b625da039b16e9b9b55ab2425afe.tar.gz platform-system-core-a0360ad6a365b625da039b16e9b9b55ab2425afe.tar.xz platform-system-core-a0360ad6a365b625da039b16e9b9b55ab2425afe.zip |
Merge "libziparchive: Use ReadAtOffset exclusively"
Diffstat (limited to 'base')
-rw-r--r-- | base/file.cpp | 31 | ||||
-rw-r--r-- | base/include/android-base/file.h | 11 |
2 files changed, 42 insertions, 0 deletions
diff --git a/base/file.cpp b/base/file.cpp index a2f28878e..2f697a1cc 100644 --- a/base/file.cpp +++ b/base/file.cpp | |||
@@ -153,6 +153,37 @@ bool ReadFully(int fd, void* data, size_t byte_count) { | |||
153 | return true; | 153 | return true; |
154 | } | 154 | } |
155 | 155 | ||
156 | #if defined(_WIN32) | ||
157 | // Windows implementation of pread. Note that this DOES move the file descriptors read position, | ||
158 | // but it does so atomically. | ||
159 | static ssize_t pread(int fd, void* data, size_t byte_count, off64_t offset) { | ||
160 | DWORD bytes_read; | ||
161 | OVERLAPPED overlapped; | ||
162 | memset(&overlapped, 0, sizeof(OVERLAPPED)); | ||
163 | overlapped.Offset = static_cast<DWORD>(offset); | ||
164 | overlapped.OffsetHigh = static_cast<DWORD>(offset >> 32); | ||
165 | if (!ReadFile(reinterpret_cast<HANDLE>(_get_osfhandle(fd)), data, static_cast<DWORD>(byte_count), | ||
166 | &bytes_read, &overlapped)) { | ||
167 | // In case someone tries to read errno (since this is masquerading as a POSIX call) | ||
168 | errno = EIO; | ||
169 | return -1; | ||
170 | } | ||
171 | return static_cast<ssize_t>(bytes_read); | ||
172 | } | ||
173 | #endif | ||
174 | |||
175 | bool ReadFullyAtOffset(int fd, void* data, size_t byte_count, off64_t offset) { | ||
176 | uint8_t* p = reinterpret_cast<uint8_t*>(data); | ||
177 | while (byte_count > 0) { | ||
178 | ssize_t n = TEMP_FAILURE_RETRY(pread(fd, p, byte_count, offset)); | ||
179 | if (n <= 0) return false; | ||
180 | p += n; | ||
181 | byte_count -= n; | ||
182 | offset += n; | ||
183 | } | ||
184 | return true; | ||
185 | } | ||
186 | |||
156 | bool WriteFully(int fd, const void* data, size_t byte_count) { | 187 | bool WriteFully(int fd, const void* data, size_t byte_count) { |
157 | const uint8_t* p = reinterpret_cast<const uint8_t*>(data); | 188 | const uint8_t* p = reinterpret_cast<const uint8_t*>(data); |
158 | size_t remaining = byte_count; | 189 | size_t remaining = byte_count; |
diff --git a/base/include/android-base/file.h b/base/include/android-base/file.h index 651f52962..af1489227 100644 --- a/base/include/android-base/file.h +++ b/base/include/android-base/file.h | |||
@@ -42,6 +42,17 @@ bool WriteStringToFile(const std::string& content, const std::string& path, | |||
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | bool ReadFully(int fd, void* data, size_t byte_count); | 44 | bool ReadFully(int fd, void* data, size_t byte_count); |
45 | |||
46 | // Reads `byte_count` bytes from the file descriptor at the specified offset. | ||
47 | // Returns false if there was an IO error or EOF was reached before reading `byte_count` bytes. | ||
48 | // | ||
49 | // NOTE: On Linux/Mac, this function wraps pread, which provides atomic read support without | ||
50 | // modifying the read pointer of the file descriptor. On Windows, however, the read pointer does | ||
51 | // get modified. This means that ReadFullyAtOffset can be used concurrently with other calls to the | ||
52 | // same function, but concurrently seeking or reading incrementally can lead to unexpected | ||
53 | // behavior. | ||
54 | bool ReadFullyAtOffset(int fd, void* data, size_t byte_count, off64_t offset); | ||
55 | |||
45 | bool WriteFully(int fd, const void* data, size_t byte_count); | 56 | bool WriteFully(int fd, const void* data, size_t byte_count); |
46 | 57 | ||
47 | bool RemoveFileIfExists(const std::string& path, std::string* err = nullptr); | 58 | bool RemoveFileIfExists(const std::string& path, std::string* err = nullptr); |