Apache Mesos
fs.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 #ifndef __STOUT_WINDOWS_FS_HPP__
14 #define __STOUT_WINDOWS_FS_HPP__
15 
16 #include <string>
17 
18 #include <stout/bytes.hpp>
19 #include <stout/error.hpp>
20 #include <stout/nothing.hpp>
21 #include <stout/try.hpp>
22 #include <stout/windows.hpp>
23 
24 #include <stout/os/realpath.hpp>
25 
28 
29 namespace fs {
30 
31 // Returns the total disk size in bytes.
32 inline Try<Bytes> size(const std::string& path = "/")
33 {
35  if (!real_path.isSome()) {
36  return Error(
37  "Failed to get realpath for '" + path+ "': " +
38  (real_path.isError() ? real_path.error() : "No such directory"));
39  }
40 
41  ULARGE_INTEGER free_bytes, total_bytes, total_free_bytes;
42  if (::GetDiskFreeSpaceExW(
43  internal::windows::longpath(real_path.get()).data(),
44  &free_bytes,
45  &total_bytes,
46  &total_free_bytes) == 0) {
47  return WindowsError(
48  "Error invoking 'GetDiskFreeSpaceEx' on '" + path + "'");
49  }
50 
51  return Bytes(total_bytes.QuadPart);
52 }
53 
54 
55 // Returns relative disk usage of the file system that the given path
56 // is mounted at.
57 inline Try<double> usage(const std::string& path = "/")
58 {
60  if (!real_path.isSome()) {
61  return Error(
62  "Failed to get realpath for '" + path + "': " +
63  (real_path.isError() ? real_path.error() : "No such directory"));
64  }
65 
66  ULARGE_INTEGER free_bytes, total_bytes, total_free_bytes;
67  if (::GetDiskFreeSpaceExW(
68  internal::windows::longpath(real_path.get()).data(),
69  &free_bytes,
70  &total_bytes,
71  &total_free_bytes) == 0) {
72  return WindowsError(
73  "Error invoking 'GetDiskFreeSpaceEx' on '" + path + "'");
74  }
75 
76  double used = static_cast<double>(total_bytes.QuadPart - free_bytes.QuadPart);
77  return used / total_bytes.QuadPart;
78 }
79 
80 
81 inline Try<Nothing> symlink(
82  const std::string& original,
83  const std::string& link)
84 {
85  return internal::windows::create_symbolic_link(original, link);
86 }
87 
88 
89 // Returns a list of all files matching the given pattern. This is meant to
90 // be a lightweight alternative to glob() - the only supported wildcards are
91 // `?` and `*`, and only when they appear at the tail end of `pattern` (e.g.
92 // `/root/dir/subdir/*.txt` or `/root/dir/subdir/file?.txt`.
93 inline Try<std::list<std::string>> list(const std::string& pattern)
94 {
95  const std::string dirname(Path(pattern).dirname());
96  std::list<std::string> found_files;
97  WIN32_FIND_DATAW found;
98  const SharedHandle search_handle(
99  ::FindFirstFileW(wide_stringify(pattern).data(), &found),
100  ::FindClose);
101 
102  if (search_handle.get() == INVALID_HANDLE_VALUE) {
103  // For compliance with the POSIX implementation (which uses `::glob`),
104  // return an empty list instead of an error when the path does not exist.
105  const DWORD error = ::GetLastError();
106  if (error == ERROR_FILE_NOT_FOUND || error == ERROR_PATH_NOT_FOUND) {
107  return found_files;
108  }
109 
110  return WindowsError(error, "FindFirstFile failed");
111  }
112 
113  do {
114  const std::wstring current_file(found.cFileName);
115 
116  // Ignore `.` and `..` entries.
117  if (current_file.compare(L".") != 0 && current_file.compare(L"..") != 0) {
118  found_files.push_back(path::join(dirname, stringify(current_file)));
119  }
120  } while (::FindNextFileW(search_handle.get(), &found));
121 
122  const DWORD error = ::GetLastError();
123  if (error != ERROR_NO_MORE_FILES) {
124  return WindowsError(error, "FindNextFile failed");
125  }
126 
127  return found_files;
128 }
129 
130 } // namespace fs {
131 
132 #endif // __STOUT_WINDOWS_FS_HPP__
Definition: path.hpp:29
Definition: errorbase.hpp:36
Definition: windows.hpp:72
Definition: check.hpp:33
Result< std::string > realpath(const std::string &path)
Definition: realpath.hpp:24
static Result< T > error(const std::string &message)
Definition: result.hpp:54
Try< Nothing > symlink(const std::string &original, const std::string &link)
Definition: fs.hpp:65
Definition: error.hpp:108
std::string join(const std::string &path1, const std::string &path2, const char _separator=os::PATH_SEPARATOR)
Definition: path.hpp:116
Definition: check.hpp:30
Try< Bytes > size(const std::string &path="/")
Definition: fs.hpp:32
Definition: fs.hpp:29
Try< std::list< std::string > > list(const std::string &pattern)
Definition: fs.hpp:86
Try< Bytes > used(const std::string &path="/")
Definition: fs.hpp:43
Represents a POSIX or Windows file system path and offers common path manipulations.
Definition: path.hpp:212
Try< double > usage(const std::string &path="/")
Definition: fs.hpp:55
std::string error(const std::string &msg, uint32_t code)
T & get()&
Definition: result.hpp:116
bool isSome() const
Definition: result.hpp:112
bool isError() const
Definition: result.hpp:114
std::wstring longpath(const std::string &path)
Definition: longpath.hpp:38
Definition: bytes.hpp:30
std::string stringify(int flags)
Try< Nothing > create_symbolic_link(const std::string &target, const std::string &reparse_point)
Definition: reparsepoint.hpp:321