FileSystem.h 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * Copyright (c) 2016-present, Facebook, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under both the BSD-style license (found in the
  6. * LICENSE file in the root directory of this source tree) and the GPLv2 (found
  7. * in the COPYING file in the root directory of this source tree).
  8. */
  9. #pragma once
  10. #include "utils/Range.h"
  11. #include <sys/stat.h>
  12. #include <cerrno>
  13. #include <cstdint>
  14. #include <system_error>
  15. // A small subset of `std::filesystem`.
  16. // `std::filesystem` should be a drop in replacement.
  17. // See http://en.cppreference.com/w/cpp/filesystem for documentation.
  18. namespace pzstd {
  19. // using file_status = ... causes gcc to emit a false positive warning
  20. #if defined(_MSC_VER)
  21. typedef struct ::_stat64 file_status;
  22. #else
  23. typedef struct ::stat file_status;
  24. #endif
  25. /// http://en.cppreference.com/w/cpp/filesystem/status
  26. inline file_status status(StringPiece path, std::error_code& ec) noexcept {
  27. file_status status;
  28. #if defined(_MSC_VER)
  29. const auto error = ::_stat64(path.data(), &status);
  30. #else
  31. const auto error = ::stat(path.data(), &status);
  32. #endif
  33. if (error) {
  34. ec.assign(errno, std::generic_category());
  35. } else {
  36. ec.clear();
  37. }
  38. return status;
  39. }
  40. /// http://en.cppreference.com/w/cpp/filesystem/is_regular_file
  41. inline bool is_regular_file(file_status status) noexcept {
  42. #if defined(S_ISREG)
  43. return S_ISREG(status.st_mode);
  44. #elif !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
  45. return (status.st_mode & S_IFMT) == S_IFREG;
  46. #else
  47. static_assert(false, "No POSIX stat() support.");
  48. #endif
  49. }
  50. /// http://en.cppreference.com/w/cpp/filesystem/is_regular_file
  51. inline bool is_regular_file(StringPiece path, std::error_code& ec) noexcept {
  52. return is_regular_file(status(path, ec));
  53. }
  54. /// http://en.cppreference.com/w/cpp/filesystem/is_directory
  55. inline bool is_directory(file_status status) noexcept {
  56. #if defined(S_ISDIR)
  57. return S_ISDIR(status.st_mode);
  58. #elif !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
  59. return (status.st_mode & S_IFMT) == S_IFDIR;
  60. #else
  61. static_assert(false, "NO POSIX stat() support.");
  62. #endif
  63. }
  64. /// http://en.cppreference.com/w/cpp/filesystem/is_directory
  65. inline bool is_directory(StringPiece path, std::error_code& ec) noexcept {
  66. return is_directory(status(path, ec));
  67. }
  68. /// http://en.cppreference.com/w/cpp/filesystem/file_size
  69. inline std::uintmax_t file_size(
  70. StringPiece path,
  71. std::error_code& ec) noexcept {
  72. auto stat = status(path, ec);
  73. if (ec) {
  74. return -1;
  75. }
  76. if (!is_regular_file(stat)) {
  77. ec.assign(ENOTSUP, std::generic_category());
  78. return -1;
  79. }
  80. ec.clear();
  81. return stat.st_size;
  82. }
  83. }