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 #include <utime.h> // NOLINT |
18 | 19 |
19 #include "bin/builtin.h" | 20 #include "bin/builtin.h" |
20 #include "bin/fdutils.h" | 21 #include "bin/fdutils.h" |
21 #include "bin/log.h" | 22 #include "bin/log.h" |
22 #include "platform/signal_blocker.h" | 23 #include "platform/signal_blocker.h" |
23 #include "platform/utils.h" | 24 #include "platform/utils.h" |
24 | 25 |
25 namespace dart { | 26 namespace dart { |
26 namespace bin { | 27 namespace bin { |
27 | 28 |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 VOID_TEMP_FAILURE_RETRY(close(new_fd)); | 380 VOID_TEMP_FAILURE_RETRY(close(new_fd)); |
380 if (result < 0) { | 381 if (result < 0) { |
381 VOID_NO_RETRY_EXPECTED(unlink(new_path)); | 382 VOID_NO_RETRY_EXPECTED(unlink(new_path)); |
382 errno = e; | 383 errno = e; |
383 return false; | 384 return false; |
384 } | 385 } |
385 return true; | 386 return true; |
386 } | 387 } |
387 | 388 |
388 | 389 |
| 390 static bool StatHelper(const char* name, struct stat* st) { |
| 391 if (NO_RETRY_EXPECTED(stat(name, st)) != 0) { |
| 392 return false; |
| 393 } |
| 394 // Signal an error if it's a directory. |
| 395 if (S_ISDIR(st->st_mode)) { |
| 396 errno = EISDIR; |
| 397 return false; |
| 398 } |
| 399 // Otherwise assume the caller knows what it's doing. |
| 400 return true; |
| 401 } |
| 402 |
| 403 |
389 int64_t File::LengthFromPath(const char* name) { | 404 int64_t File::LengthFromPath(const char* name) { |
390 struct stat st; | 405 struct stat st; |
391 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { | 406 if (!StatHelper(name, &st)) { |
392 // Signal an error if it's a directory. | 407 return -1; |
393 if (S_ISDIR(st.st_mode)) { | |
394 errno = EISDIR; | |
395 return -1; | |
396 } | |
397 // Otherwise assume the caller knows what it's doing. | |
398 return st.st_size; | |
399 } | 408 } |
400 return -1; | 409 return st.st_size; |
401 } | 410 } |
402 | 411 |
403 | 412 |
404 void File::Stat(const char* name, int64_t* data) { | 413 void File::Stat(const char* name, int64_t* data) { |
405 struct stat st; | 414 struct stat st; |
406 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { | 415 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { |
407 if (S_ISREG(st.st_mode)) { | 416 if (S_ISREG(st.st_mode)) { |
408 data[kType] = kIsFile; | 417 data[kType] = kIsFile; |
409 } else if (S_ISDIR(st.st_mode)) { | 418 } else if (S_ISDIR(st.st_mode)) { |
410 data[kType] = kIsDirectory; | 419 data[kType] = kIsDirectory; |
411 } else if (S_ISLNK(st.st_mode)) { | 420 } else if (S_ISLNK(st.st_mode)) { |
412 data[kType] = kIsLink; | 421 data[kType] = kIsLink; |
413 } else { | 422 } else { |
414 data[kType] = kDoesNotExist; | 423 data[kType] = kDoesNotExist; |
415 } | 424 } |
416 data[kCreatedTime] = static_cast<int64_t>(st.st_ctime) * 1000; | 425 data[kCreatedTime] = static_cast<int64_t>(st.st_ctime) * 1000; |
417 data[kModifiedTime] = static_cast<int64_t>(st.st_mtime) * 1000; | 426 data[kModifiedTime] = static_cast<int64_t>(st.st_mtime) * 1000; |
418 data[kAccessedTime] = static_cast<int64_t>(st.st_atime) * 1000; | 427 data[kAccessedTime] = static_cast<int64_t>(st.st_atime) * 1000; |
419 data[kMode] = st.st_mode; | 428 data[kMode] = st.st_mode; |
420 data[kSize] = st.st_size; | 429 data[kSize] = st.st_size; |
421 } else { | 430 } else { |
422 data[kType] = kDoesNotExist; | 431 data[kType] = kDoesNotExist; |
423 } | 432 } |
424 } | 433 } |
425 | 434 |
426 | 435 |
427 time_t File::LastModified(const char* name) { | 436 time_t File::LastModified(const char* name) { |
428 struct stat st; | 437 struct stat st; |
429 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { | 438 if (!StatHelper(name, &st)) { |
430 // Signal an error if it's a directory. | 439 return -1; |
431 if (S_ISDIR(st.st_mode)) { | |
432 errno = EISDIR; | |
433 return -1; | |
434 } | |
435 // Otherwise assume the caller knows what it's doing. | |
436 return st.st_mtime; | |
437 } | 440 } |
438 return -1; | 441 return st.st_mtime; |
439 } | 442 } |
440 | 443 |
441 | 444 |
| 445 time_t File::LastAccessed(const char* name) { |
| 446 struct stat st; |
| 447 if (!StatHelper(name, &st)) { |
| 448 return -1; |
| 449 } |
| 450 return st.st_atime; |
| 451 } |
| 452 |
| 453 |
| 454 bool File::SetLastAccessed(const char* name, int64_t millis) { |
| 455 // First get the current times. |
| 456 struct stat st; |
| 457 if (!StatHelper(name, &st)) { |
| 458 return false; |
| 459 } |
| 460 |
| 461 // Set the new time: |
| 462 struct utimbuf times; |
| 463 times.actime = millis / kMillisecondsPerSecond; |
| 464 times.modtime = st.st_mtime; |
| 465 return utime(name, ×) == 0; |
| 466 } |
| 467 |
| 468 |
| 469 bool File::SetLastModified(const char* name, int64_t millis) { |
| 470 // First get the current times. |
| 471 struct stat st; |
| 472 if (!StatHelper(name, &st)) { |
| 473 return false; |
| 474 } |
| 475 |
| 476 // Set the new time: |
| 477 struct utimbuf times; |
| 478 times.actime = st.st_atime; |
| 479 times.modtime = millis / kMillisecondsPerSecond; |
| 480 return utime(name, ×) == 0; |
| 481 } |
| 482 |
| 483 |
442 const char* File::LinkTarget(const char* pathname) { | 484 const char* File::LinkTarget(const char* pathname) { |
443 struct stat link_stats; | 485 struct stat link_stats; |
444 if (lstat(pathname, &link_stats) != 0) { | 486 if (lstat(pathname, &link_stats) != 0) { |
445 return NULL; | 487 return NULL; |
446 } | 488 } |
447 if (!S_ISLNK(link_stats.st_mode)) { | 489 if (!S_ISLNK(link_stats.st_mode)) { |
448 errno = ENOENT; | 490 errno = ENOENT; |
449 return NULL; | 491 return NULL; |
450 } | 492 } |
451 size_t target_size = link_stats.st_size; | 493 size_t target_size = link_stats.st_size; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 return ((file_1_info.st_ino == file_2_info.st_ino) && | 568 return ((file_1_info.st_ino == file_2_info.st_ino) && |
527 (file_1_info.st_dev == file_2_info.st_dev)) | 569 (file_1_info.st_dev == file_2_info.st_dev)) |
528 ? File::kIdentical | 570 ? File::kIdentical |
529 : File::kDifferent; | 571 : File::kDifferent; |
530 } | 572 } |
531 | 573 |
532 } // namespace bin | 574 } // namespace bin |
533 } // namespace dart | 575 } // namespace dart |
534 | 576 |
535 #endif // defined(TARGET_OS_ANDROID) | 577 #endif // defined(TARGET_OS_ANDROID) |
OLD | NEW |