| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 #if defined(TARGET_OS_ANDROID) | 6 #if defined(TARGET_OS_ANDROID) |
| 7 | 7 |
| 8 #include "bin/file.h" | 8 #include "bin/file.h" |
| 9 | 9 |
| 10 #include <errno.h> // NOLINT | 10 #include <errno.h> // NOLINT |
| 11 #include <fcntl.h> // NOLINT | 11 #include <fcntl.h> // NOLINT |
| 12 #include <libgen.h> // NOLINT | 12 #include <libgen.h> // NOLINT |
| 13 #include <sys/mman.h> // NOLINT | 13 #include <sys/mman.h> // NOLINT |
| 14 #include <sys/sendfile.h> // NOLINT | 14 #include <sys/sendfile.h> // NOLINT |
| 15 #include <sys/stat.h> // NOLINT | 15 #include <sys/stat.h> // NOLINT |
| 16 #include <sys/types.h> // NOLINT | 16 #include <sys/types.h> // NOLINT |
| 17 #include <unistd.h> // NOLINT | 17 #include <unistd.h> // NOLINT |
| 18 | 18 |
| 19 #include "bin/builtin.h" | 19 #include "bin/builtin.h" |
| 20 #include "bin/log.h" | 20 #include "bin/log.h" |
| 21 | 21 |
| 22 #include "platform/signal_blocker.h" | 22 #include "platform/signal_blocker.h" |
| 23 #include "platform/utils.h" | 23 #include "platform/utils.h" |
| 24 | 24 |
| 25 namespace dart { | 25 namespace dart { |
| 26 namespace bin { | 26 namespace bin { |
| 27 | 27 |
| 28 class FileHandle { | 28 class FileHandle { |
| 29 public: | 29 public: |
| 30 explicit FileHandle(int fd) : fd_(fd) { } | 30 explicit FileHandle(int fd) : fd_(fd) {} |
| 31 ~FileHandle() { } | 31 ~FileHandle() {} |
| 32 int fd() const { return fd_; } | 32 int fd() const { return fd_; } |
| 33 void set_fd(int fd) { fd_ = fd; } | 33 void set_fd(int fd) { fd_ = fd; } |
| 34 | 34 |
| 35 private: | 35 private: |
| 36 int fd_; | 36 int fd_; |
| 37 | 37 |
| 38 DISALLOW_COPY_AND_ASSIGN(FileHandle); | 38 DISALLOW_COPY_AND_ASSIGN(FileHandle); |
| 39 }; | 39 }; |
| 40 | 40 |
| 41 | 41 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 switch (type) { | 84 switch (type) { |
| 85 case kReadOnly: | 85 case kReadOnly: |
| 86 prot = PROT_READ; | 86 prot = PROT_READ; |
| 87 break; | 87 break; |
| 88 case kReadExecute: | 88 case kReadExecute: |
| 89 prot = PROT_READ | PROT_EXEC; | 89 prot = PROT_READ | PROT_EXEC; |
| 90 break; | 90 break; |
| 91 default: | 91 default: |
| 92 return NULL; | 92 return NULL; |
| 93 } | 93 } |
| 94 void* addr = mmap(NULL, length, prot, MAP_PRIVATE, | 94 void* addr = mmap(NULL, length, prot, MAP_PRIVATE, handle_->fd(), position); |
| 95 handle_->fd(), position); | |
| 96 if (addr == MAP_FAILED) { | 95 if (addr == MAP_FAILED) { |
| 97 return NULL; | 96 return NULL; |
| 98 } | 97 } |
| 99 return addr; | 98 return addr; |
| 100 } | 99 } |
| 101 | 100 |
| 102 | 101 |
| 103 int64_t File::Read(void* buffer, int64_t num_bytes) { | 102 int64_t File::Read(void* buffer, int64_t num_bytes) { |
| 104 ASSERT(handle_->fd() >= 0); | 103 ASSERT(handle_->fd() >= 0); |
| 105 return TEMP_FAILURE_RETRY(read(handle_->fd(), buffer, num_bytes)); | 104 return TEMP_FAILURE_RETRY(read(handle_->fd(), buffer, num_bytes)); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 int new_fd = TEMP_FAILURE_RETRY( | 312 int new_fd = TEMP_FAILURE_RETRY( |
| 314 open(new_path, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, st.st_mode)); | 313 open(new_path, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, st.st_mode)); |
| 315 if (new_fd < 0) { | 314 if (new_fd < 0) { |
| 316 VOID_TEMP_FAILURE_RETRY(close(old_fd)); | 315 VOID_TEMP_FAILURE_RETRY(close(old_fd)); |
| 317 return false; | 316 return false; |
| 318 } | 317 } |
| 319 off_t offset = 0; | 318 off_t offset = 0; |
| 320 int result = 1; | 319 int result = 1; |
| 321 while (result > 0) { | 320 while (result > 0) { |
| 322 // Loop to ensure we copy everything, and not only up to 2GB. | 321 // Loop to ensure we copy everything, and not only up to 2GB. |
| 323 result = NO_RETRY_EXPECTED( | 322 result = NO_RETRY_EXPECTED(sendfile(new_fd, old_fd, &offset, kMaxUint32)); |
| 324 sendfile(new_fd, old_fd, &offset, kMaxUint32)); | |
| 325 } | 323 } |
| 326 // From sendfile man pages: | 324 // From sendfile man pages: |
| 327 // Applications may wish to fall back to read(2)/write(2) in the case | 325 // Applications may wish to fall back to read(2)/write(2) in the case |
| 328 // where sendfile() fails with EINVAL or ENOSYS. | 326 // where sendfile() fails with EINVAL or ENOSYS. |
| 329 if ((result < 0) && ((errno == EINVAL) || (errno == ENOSYS))) { | 327 if ((result < 0) && ((errno == EINVAL) || (errno == ENOSYS))) { |
| 330 const intptr_t kBufferSize = 8 * KB; | 328 const intptr_t kBufferSize = 8 * KB; |
| 331 uint8_t buffer[kBufferSize]; | 329 uint8_t buffer[kBufferSize]; |
| 332 while ((result = TEMP_FAILURE_RETRY( | 330 while ((result = TEMP_FAILURE_RETRY(read(old_fd, buffer, kBufferSize))) > |
| 333 read(old_fd, buffer, kBufferSize))) > 0) { | 331 0) { |
| 334 int wrote = TEMP_FAILURE_RETRY(write(new_fd, buffer, result)); | 332 int wrote = TEMP_FAILURE_RETRY(write(new_fd, buffer, result)); |
| 335 if (wrote != result) { | 333 if (wrote != result) { |
| 336 result = -1; | 334 result = -1; |
| 337 break; | 335 break; |
| 338 } | 336 } |
| 339 } | 337 } |
| 340 } | 338 } |
| 341 int e = errno; | 339 int e = errno; |
| 342 VOID_TEMP_FAILURE_RETRY(close(old_fd)); | 340 VOID_TEMP_FAILURE_RETRY(close(old_fd)); |
| 343 VOID_TEMP_FAILURE_RETRY(close(new_fd)); | 341 VOID_TEMP_FAILURE_RETRY(close(new_fd)); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 | 497 |
| 500 | 498 |
| 501 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { | 499 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { |
| 502 struct stat file_1_info; | 500 struct stat file_1_info; |
| 503 struct stat file_2_info; | 501 struct stat file_2_info; |
| 504 if ((NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1) || | 502 if ((NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1) || |
| 505 (NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1)) { | 503 (NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1)) { |
| 506 return File::kError; | 504 return File::kError; |
| 507 } | 505 } |
| 508 return ((file_1_info.st_ino == file_2_info.st_ino) && | 506 return ((file_1_info.st_ino == file_2_info.st_ino) && |
| 509 (file_1_info.st_dev == file_2_info.st_dev)) ? | 507 (file_1_info.st_dev == file_2_info.st_dev)) |
| 510 File::kIdentical : | 508 ? File::kIdentical |
| 511 File::kDifferent; | 509 : File::kDifferent; |
| 512 } | 510 } |
| 513 | 511 |
| 514 } // namespace bin | 512 } // namespace bin |
| 515 } // namespace dart | 513 } // namespace dart |
| 516 | 514 |
| 517 #endif // defined(TARGET_OS_ANDROID) | 515 #endif // defined(TARGET_OS_ANDROID) |
| OLD | NEW |