| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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_FUCHSIA) | 6 #if defined(TARGET_OS_FUCHSIA) |
| 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/stat.h> // NOLINT | 14 #include <sys/stat.h> // NOLINT |
| 15 #include <sys/types.h> // NOLINT | 15 #include <sys/types.h> // NOLINT |
| 16 #include <unistd.h> // NOLINT | 16 #include <unistd.h> // NOLINT |
| 17 #include <utime.h> // NOLINT |
| 17 | 18 |
| 18 #include "bin/builtin.h" | 19 #include "bin/builtin.h" |
| 19 #include "bin/fdutils.h" | 20 #include "bin/fdutils.h" |
| 20 #include "bin/log.h" | 21 #include "bin/log.h" |
| 21 #include "platform/signal_blocker.h" | 22 #include "platform/signal_blocker.h" |
| 22 #include "platform/utils.h" | 23 #include "platform/utils.h" |
| 23 | 24 |
| 24 namespace dart { | 25 namespace dart { |
| 25 namespace bin { | 26 namespace bin { |
| 26 | 27 |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 if (result < 0) { | 353 if (result < 0) { |
| 353 int e = errno; | 354 int e = errno; |
| 354 VOID_NO_RETRY_EXPECTED(unlink(new_path)); | 355 VOID_NO_RETRY_EXPECTED(unlink(new_path)); |
| 355 errno = e; | 356 errno = e; |
| 356 return false; | 357 return false; |
| 357 } | 358 } |
| 358 return true; | 359 return true; |
| 359 } | 360 } |
| 360 | 361 |
| 361 | 362 |
| 363 static bool StatHelper(const char* name, struct stat64* st) { |
| 364 if (NO_RETRY_EXPECTED(stat64(name, st)) != 0) { |
| 365 return false; |
| 366 } |
| 367 // Signal an error if it's a directory. |
| 368 if (S_ISDIR(st->st_mode)) { |
| 369 errno = EISDIR; |
| 370 return false; |
| 371 } |
| 372 // Otherwise assume the caller knows what it's doing. |
| 373 return true; |
| 374 } |
| 375 |
| 376 |
| 362 int64_t File::LengthFromPath(const char* name) { | 377 int64_t File::LengthFromPath(const char* name) { |
| 363 struct stat st; | 378 struct stat64 st; |
| 364 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { | 379 if (!StatHelper(name, &st)) { |
| 365 // Signal an error if it's a directory. | 380 return -1; |
| 366 if (S_ISDIR(st.st_mode)) { | |
| 367 errno = EISDIR; | |
| 368 return -1; | |
| 369 } | |
| 370 // Otherwise assume the caller knows what it's doing. | |
| 371 return st.st_size; | |
| 372 } | 381 } |
| 373 return -1; | 382 return st.st_size; |
| 374 } | 383 } |
| 375 | 384 |
| 376 | 385 |
| 377 void File::Stat(const char* name, int64_t* data) { | 386 void File::Stat(const char* name, int64_t* data) { |
| 378 struct stat st; | 387 struct stat st; |
| 379 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { | 388 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { |
| 380 if (S_ISREG(st.st_mode)) { | 389 if (S_ISREG(st.st_mode)) { |
| 381 data[kType] = kIsFile; | 390 data[kType] = kIsFile; |
| 382 } else if (S_ISDIR(st.st_mode)) { | 391 } else if (S_ISDIR(st.st_mode)) { |
| 383 data[kType] = kIsDirectory; | 392 data[kType] = kIsDirectory; |
| 384 } else if (S_ISLNK(st.st_mode)) { | 393 } else if (S_ISLNK(st.st_mode)) { |
| 385 data[kType] = kIsLink; | 394 data[kType] = kIsLink; |
| 386 } else { | 395 } else { |
| 387 data[kType] = kDoesNotExist; | 396 data[kType] = kDoesNotExist; |
| 388 } | 397 } |
| 389 data[kCreatedTime] = static_cast<int64_t>(st.st_ctime) * 1000; | 398 data[kCreatedTime] = static_cast<int64_t>(st.st_ctime) * 1000; |
| 390 data[kModifiedTime] = static_cast<int64_t>(st.st_mtime) * 1000; | 399 data[kModifiedTime] = static_cast<int64_t>(st.st_mtime) * 1000; |
| 391 data[kAccessedTime] = static_cast<int64_t>(st.st_atime) * 1000; | 400 data[kAccessedTime] = static_cast<int64_t>(st.st_atime) * 1000; |
| 392 data[kMode] = st.st_mode; | 401 data[kMode] = st.st_mode; |
| 393 data[kSize] = st.st_size; | 402 data[kSize] = st.st_size; |
| 394 } else { | 403 } else { |
| 395 data[kType] = kDoesNotExist; | 404 data[kType] = kDoesNotExist; |
| 396 } | 405 } |
| 397 } | 406 } |
| 398 | 407 |
| 399 | 408 |
| 400 time_t File::LastModified(const char* name) { | 409 time_t File::LastModified(const char* name) { |
| 401 struct stat st; | 410 struct stat st; |
| 402 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) { | 411 if (!StatHelper(name, &st)) { |
| 403 // Signal an error if it's a directory. | 412 return -1; |
| 404 if (S_ISDIR(st.st_mode)) { | |
| 405 errno = EISDIR; | |
| 406 return -1; | |
| 407 } | |
| 408 // Otherwise assume the caller knows what it's doing. | |
| 409 return st.st_mtime; | |
| 410 } | 413 } |
| 411 return -1; | 414 return st.st_mtime; |
| 412 } | 415 } |
| 413 | 416 |
| 414 | 417 |
| 418 time_t File::LastAccessed(const char* name) { |
| 419 struct stat st; |
| 420 if (!StatHelper(name, &st)) { |
| 421 return -1; |
| 422 } |
| 423 return st.st_atime; |
| 424 } |
| 425 |
| 426 |
| 427 bool File::SetLastAccessed(const char* name, int64_t millis) { |
| 428 // First get the current times. |
| 429 struct stat st; |
| 430 if (!StatHelper(name, &st)) { |
| 431 return false; |
| 432 } |
| 433 |
| 434 // Set the new time: |
| 435 struct utimbuf times; |
| 436 times.actime = millis / kMillisecondsPerSecond; |
| 437 times.modtime = st.st_mtime; |
| 438 return utime(name, ×) == 0; |
| 439 } |
| 440 |
| 441 |
| 442 bool File::SetLastModified(const char* name, int64_t millis) { |
| 443 // First get the current times. |
| 444 struct stat st; |
| 445 if (!StatHelper(name, &st)) { |
| 446 return false; |
| 447 } |
| 448 |
| 449 // Set the new time: |
| 450 struct utimbuf times; |
| 451 times.actime = st.st_atime; |
| 452 times.modtime = millis / kMillisecondsPerSecond; |
| 453 return utime(name, ×) == 0; |
| 454 } |
| 455 |
| 456 |
| 415 const char* File::LinkTarget(const char* pathname) { | 457 const char* File::LinkTarget(const char* pathname) { |
| 416 struct stat link_stats; | 458 struct stat link_stats; |
| 417 if (lstat(pathname, &link_stats) != 0) { | 459 if (lstat(pathname, &link_stats) != 0) { |
| 418 return NULL; | 460 return NULL; |
| 419 } | 461 } |
| 420 if (!S_ISLNK(link_stats.st_mode)) { | 462 if (!S_ISLNK(link_stats.st_mode)) { |
| 421 errno = ENOENT; | 463 errno = ENOENT; |
| 422 return NULL; | 464 return NULL; |
| 423 } | 465 } |
| 424 size_t target_size = link_stats.st_size; | 466 size_t target_size = link_stats.st_size; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 return ((file_1_info.st_ino == file_2_info.st_ino) && | 546 return ((file_1_info.st_ino == file_2_info.st_ino) && |
| 505 (file_1_info.st_dev == file_2_info.st_dev)) | 547 (file_1_info.st_dev == file_2_info.st_dev)) |
| 506 ? File::kIdentical | 548 ? File::kIdentical |
| 507 : File::kDifferent; | 549 : File::kDifferent; |
| 508 } | 550 } |
| 509 | 551 |
| 510 } // namespace bin | 552 } // namespace bin |
| 511 } // namespace dart | 553 } // namespace dart |
| 512 | 554 |
| 513 #endif // defined(TARGET_OS_FUCHSIA) | 555 #endif // defined(TARGET_OS_FUCHSIA) |
| OLD | NEW |