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_LINUX) | 6 #if defined(TARGET_OS_LINUX) |
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 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 VOID_TEMP_FAILURE_RETRY(close(new_fd)); | 381 VOID_TEMP_FAILURE_RETRY(close(new_fd)); |
381 if (result < 0) { | 382 if (result < 0) { |
382 VOID_NO_RETRY_EXPECTED(unlink(new_path)); | 383 VOID_NO_RETRY_EXPECTED(unlink(new_path)); |
383 errno = e; | 384 errno = e; |
384 return false; | 385 return false; |
385 } | 386 } |
386 return true; | 387 return true; |
387 } | 388 } |
388 | 389 |
389 | 390 |
| 391 static bool StatHelper(const char* name, struct stat64* st) { |
| 392 if (TEMP_FAILURE_RETRY(stat64(name, st)) != 0) { |
| 393 return false; |
| 394 } |
| 395 // Signal an error if it's a directory. |
| 396 if (S_ISDIR(st->st_mode)) { |
| 397 errno = EISDIR; |
| 398 return false; |
| 399 } |
| 400 // Otherwise assume the caller knows what it's doing. |
| 401 return true; |
| 402 } |
| 403 |
| 404 |
390 int64_t File::LengthFromPath(const char* name) { | 405 int64_t File::LengthFromPath(const char* name) { |
391 struct stat64 st; | 406 struct stat64 st; |
392 if (TEMP_FAILURE_RETRY(stat64(name, &st)) == 0) { | 407 if (!StatHelper(name, &st)) { |
393 // Signal an error if it's a directory. | 408 return -1; |
394 if (S_ISDIR(st.st_mode)) { | |
395 errno = EISDIR; | |
396 return -1; | |
397 } | |
398 // Otherwise assume the caller knows what it's doing. | |
399 return st.st_size; | |
400 } | 409 } |
401 return -1; | 410 return st.st_size; |
402 } | 411 } |
403 | 412 |
404 | 413 |
405 static int64_t TimespecToMilliseconds(const struct timespec& t) { | 414 static int64_t TimespecToMilliseconds(const struct timespec& t) { |
406 return static_cast<int64_t>(t.tv_sec) * 1000L + | 415 return static_cast<int64_t>(t.tv_sec) * 1000L + |
407 static_cast<int64_t>(t.tv_nsec) / 1000000L; | 416 static_cast<int64_t>(t.tv_nsec) / 1000000L; |
408 } | 417 } |
409 | 418 |
410 | 419 |
411 void File::Stat(const char* name, int64_t* data) { | 420 void File::Stat(const char* name, int64_t* data) { |
(...skipping 14 matching lines...) Expand all Loading... |
426 data[kMode] = st.st_mode; | 435 data[kMode] = st.st_mode; |
427 data[kSize] = st.st_size; | 436 data[kSize] = st.st_size; |
428 } else { | 437 } else { |
429 data[kType] = kDoesNotExist; | 438 data[kType] = kDoesNotExist; |
430 } | 439 } |
431 } | 440 } |
432 | 441 |
433 | 442 |
434 time_t File::LastModified(const char* name) { | 443 time_t File::LastModified(const char* name) { |
435 struct stat64 st; | 444 struct stat64 st; |
436 if (TEMP_FAILURE_RETRY(stat64(name, &st)) == 0) { | 445 if (!StatHelper(name, &st)) { |
437 // Signal an error if it's a directory. | 446 return -1; |
438 if (S_ISDIR(st.st_mode)) { | |
439 errno = EISDIR; | |
440 return -1; | |
441 } | |
442 // Otherwise assume the caller knows what it's doing. | |
443 return st.st_mtime; | |
444 } | 447 } |
445 return -1; | 448 return st.st_mtime; |
446 } | 449 } |
447 | 450 |
448 | 451 |
| 452 time_t File::LastAccessed(const char* name) { |
| 453 struct stat64 st; |
| 454 if (!StatHelper(name, &st)) { |
| 455 return -1; |
| 456 } |
| 457 return st.st_atime; |
| 458 } |
| 459 |
| 460 |
| 461 bool File::SetLastAccessed(const char* name, int64_t millis) { |
| 462 // First get the current times. |
| 463 struct stat64 st; |
| 464 if (!StatHelper(name, &st)) { |
| 465 return false; |
| 466 } |
| 467 |
| 468 // Set the new time: |
| 469 struct utimbuf times; |
| 470 times.actime = millis / kMillisecondsPerSecond; |
| 471 times.modtime = st.st_mtime; |
| 472 return utime(name, ×) == 0; |
| 473 } |
| 474 |
| 475 |
| 476 bool File::SetLastModified(const char* name, int64_t millis) { |
| 477 // First get the current times. |
| 478 struct stat64 st; |
| 479 if (!StatHelper(name, &st)) { |
| 480 return false; |
| 481 } |
| 482 |
| 483 // Set the new time: |
| 484 struct utimbuf times; |
| 485 times.actime = st.st_atime; |
| 486 times.modtime = millis / kMillisecondsPerSecond; |
| 487 return utime(name, ×) == 0; |
| 488 } |
| 489 |
| 490 |
449 const char* File::LinkTarget(const char* pathname) { | 491 const char* File::LinkTarget(const char* pathname) { |
450 struct stat64 link_stats; | 492 struct stat64 link_stats; |
451 if (TEMP_FAILURE_RETRY(lstat64(pathname, &link_stats)) != 0) { | 493 if (TEMP_FAILURE_RETRY(lstat64(pathname, &link_stats)) != 0) { |
452 return NULL; | 494 return NULL; |
453 } | 495 } |
454 if (!S_ISLNK(link_stats.st_mode)) { | 496 if (!S_ISLNK(link_stats.st_mode)) { |
455 errno = ENOENT; | 497 errno = ENOENT; |
456 return NULL; | 498 return NULL; |
457 } | 499 } |
458 // Don't rely on the link_stats.st_size for the size of the link | 500 // Don't rely on the link_stats.st_size for the size of the link |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 return ((file_1_info.st_ino == file_2_info.st_ino) && | 581 return ((file_1_info.st_ino == file_2_info.st_ino) && |
540 (file_1_info.st_dev == file_2_info.st_dev)) | 582 (file_1_info.st_dev == file_2_info.st_dev)) |
541 ? File::kIdentical | 583 ? File::kIdentical |
542 : File::kDifferent; | 584 : File::kDifferent; |
543 } | 585 } |
544 | 586 |
545 } // namespace bin | 587 } // namespace bin |
546 } // namespace dart | 588 } // namespace dart |
547 | 589 |
548 #endif // defined(TARGET_OS_LINUX) | 590 #endif // defined(TARGET_OS_LINUX) |
OLD | NEW |