| 618 | |
| 619 | |
| 620 | Future<Try<tuple<size_t, string>, FilesError>> FilesProcess::_read( |
| 621 | size_t offset, |
| 622 | Option<size_t> length, |
| 623 | const string& path) |
| 624 | { |
| 625 | Result<string> resolvedPath = resolve(path); |
| 626 | |
| 627 | if (resolvedPath.isError()) { |
| 628 | return FilesError(FilesError::Type::INVALID, resolvedPath.error() + ".\n"); |
| 629 | } else if (!resolvedPath.isSome()) { |
| 630 | return FilesError(FilesError::Type::NOT_FOUND); |
| 631 | } |
| 632 | |
| 633 | // Don't read directories. |
| 634 | if (os::stat::isdir(resolvedPath.get())) { |
| 635 | return FilesError(FilesError::Type::INVALID, "Cannot read a directory.\n"); |
| 636 | } |
| 637 | |
| 638 | // TODO(benh): Cache file descriptors so we aren't constantly |
| 639 | // opening them and paging the data in from disk. |
| 640 | Try<int_fd> fd = os::open(resolvedPath.get(), O_RDONLY | O_CLOEXEC); |
| 641 | if (fd.isError()) { |
| 642 | string error = strings::format( |
| 643 | "Failed to open file at '%s': %s", |
| 644 | resolvedPath.get(), |
| 645 | fd.error()).get(); |
| 646 | LOG(WARNING) << error; |
| 647 | return FilesError(FilesError::Type::UNKNOWN, error + ".\n"); |
| 648 | } |
| 649 | |
| 650 | Try<off_t> lseek = os::lseek(fd.get(), 0, SEEK_END); |
| 651 | if (lseek.isError()) { |
| 652 | string error = strings::format( |
| 653 | "Failed to open file at '%s': %s", |
| 654 | resolvedPath.get(), |
| 655 | os::strerror(errno)).get(); |
| 656 | |
| 657 | LOG(WARNING) << error; |
| 658 | os::close(fd.get()); |
| 659 | return FilesError(FilesError::Type::UNKNOWN, error + ".\n"); |
| 660 | } |
| 661 | |
| 662 | const off_t size = lseek.get(); |
| 663 | |
| 664 | if (offset >= static_cast<size_t>(size)) { |
| 665 | os::close(fd.get()); |
| 666 | return std::make_tuple(size, ""); |
| 667 | } |
| 668 | |
| 669 | if (length.isNone()) { |
| 670 | length = size - offset; |
| 671 | } |
| 672 | |
| 673 | // Return the size of file if length is 0. |
| 674 | if (length == 0) { |
| 675 | os::close(fd.get()); |
| 676 | return std::make_tuple(size, ""); |
| 677 | } |
nothing calls this directly
no test coverage detected