• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
11 #include "utils/Range.h"
12 
13 #include <sys/stat.h>
14 #include <cerrno>
15 #include <cstdint>
16 #include <system_error>
17 
18 // A small subset of `std::filesystem`.
19 // `std::filesystem` should be a drop in replacement.
20 // See http://en.cppreference.com/w/cpp/filesystem for documentation.
21 
22 namespace pzstd {
23 
24 // using file_status = ... causes gcc to emit a false positive warning
25 #if defined(_MSC_VER)
26 typedef struct ::_stat64 file_status;
27 #else
28 typedef struct ::stat file_status;
29 #endif
30 
31 /// http://en.cppreference.com/w/cpp/filesystem/status
status(StringPiece path,std::error_code & ec)32 inline file_status status(StringPiece path, std::error_code& ec) noexcept {
33   file_status status;
34 #if defined(_MSC_VER)
35   const auto error = ::_stat64(path.data(), &status);
36 #else
37   const auto error = ::stat(path.data(), &status);
38 #endif
39   if (error) {
40     ec.assign(errno, std::generic_category());
41   } else {
42     ec.clear();
43   }
44   return status;
45 }
46 
47 /// http://en.cppreference.com/w/cpp/filesystem/is_regular_file
is_regular_file(file_status status)48 inline bool is_regular_file(file_status status) noexcept {
49 #if defined(S_ISREG)
50   return S_ISREG(status.st_mode);
51 #elif !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
52   return (status.st_mode & S_IFMT) == S_IFREG;
53 #else
54   static_assert(false, "No POSIX stat() support.");
55 #endif
56 }
57 
58 /// http://en.cppreference.com/w/cpp/filesystem/is_regular_file
is_regular_file(StringPiece path,std::error_code & ec)59 inline bool is_regular_file(StringPiece path, std::error_code& ec) noexcept {
60   return is_regular_file(status(path, ec));
61 }
62 
63 /// http://en.cppreference.com/w/cpp/filesystem/is_directory
is_directory(file_status status)64 inline bool is_directory(file_status status) noexcept {
65 #if defined(S_ISDIR)
66   return S_ISDIR(status.st_mode);
67 #elif !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
68   return (status.st_mode & S_IFMT) == S_IFDIR;
69 #else
70   static_assert(false, "NO POSIX stat() support.");
71 #endif
72 }
73 
74 /// http://en.cppreference.com/w/cpp/filesystem/is_directory
is_directory(StringPiece path,std::error_code & ec)75 inline bool is_directory(StringPiece path, std::error_code& ec) noexcept {
76   return is_directory(status(path, ec));
77 }
78 
79 /// http://en.cppreference.com/w/cpp/filesystem/file_size
file_size(StringPiece path,std::error_code & ec)80 inline std::uintmax_t file_size(
81     StringPiece path,
82     std::error_code& ec) noexcept {
83   auto stat = status(path, ec);
84   if (ec) {
85     return -1;
86   }
87   if (!is_regular_file(stat)) {
88     ec.assign(ENOTSUP, std::generic_category());
89     return -1;
90   }
91   ec.clear();
92   return stat.st_size;
93 }
94 }
95