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 |