Apache Mesos
stat.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_OS_POSIX_STAT_HPP__
14 #define __STOUT_OS_POSIX_STAT_HPP__
15 
16 #include <sys/stat.h>
17 #include <sys/statvfs.h>
18 
19 #include <string>
20 
21 #include <stout/bytes.hpp>
22 #include <stout/try.hpp>
23 #include <stout/unreachable.hpp>
24 
25 #include <stout/os/int_fd.hpp>
26 
27 
28 namespace os {
29 
30 namespace stat {
31 
32 // Specify whether symlink path arguments should be followed or
33 // not. APIs in the os::stat family that take a FollowSymlink
34 // argument all provide FollowSymlink::FOLLOW_SYMLINK as the default value,
35 // so they will follow symlinks unless otherwise specified.
36 enum class FollowSymlink
37 {
40 };
41 
42 
43 namespace internal {
44 
46  const std::string& path,
47  const FollowSymlink follow)
48 {
49  struct ::stat s;
50 
51  switch (follow) {
53  if (::lstat(path.c_str(), &s) < 0) {
54  return ErrnoError("Failed to lstat '" + path + "'");
55  }
56  return s;
58  if (::stat(path.c_str(), &s) < 0) {
59  return ErrnoError("Failed to stat '" + path + "'");
60  }
61  return s;
62  }
63 
64  UNREACHABLE();
65 }
66 
67 
68 inline Try<struct ::stat> stat(const int_fd fd)
69 {
70  struct ::stat s;
71 
72  if (::fstat(fd, &s) < 0) {
73  return ErrnoError();
74  }
75  return s;
76 }
77 
78 } // namespace internal {
79 
80 inline bool islink(const std::string& path)
81 {
82  // By definition, you don't follow symlinks when trying
83  // to find whether a path is a link. If you followed it,
84  // it wouldn't ever be a link.
87  return s.isSome() && S_ISLNK(s->st_mode);
88 }
89 
90 
91 inline bool isdir(
92  const std::string& path,
94 {
95  Try<struct ::stat> s = internal::stat(path, follow);
96  return s.isSome() && S_ISDIR(s->st_mode);
97 }
98 
99 
100 // TODO(andschwa): Share logic with other overload.
101 inline bool isdir(const int_fd fd)
102 {
104  return s.isSome() && S_ISDIR(s->st_mode);
105 }
106 
107 
108 inline bool isfile(
109  const std::string& path,
111 {
112  Try<struct ::stat> s = internal::stat(path, follow);
113  return s.isSome() && S_ISREG(s->st_mode);
114 }
115 
116 
117 inline bool issocket(
118  const std::string& path,
120 {
121  Try<struct ::stat> s = internal::stat(path, follow);
122  return s.isSome() && S_ISSOCK(s->st_mode);
123 }
124 
125 
126 // Returns the size in Bytes of a given file system entry. When
127 // applied to a symbolic link with `follow` set to
128 // `DO_NOT_FOLLOW_SYMLINK`, this will return the length of the entry
129 // name (strlen).
131  const std::string& path,
133 {
134  Try<struct ::stat> s = internal::stat(path, follow);
135  if (s.isError()) {
136  return Error(s.error());
137  }
138 
139  return Bytes(s->st_size);
140 }
141 
142 
143 // TODO(andschwa): Share logic with other overload.
144 inline Try<Bytes> size(const int_fd fd)
145 {
147  if (s.isError()) {
148  return Error(s.error());
149  }
150 
151  return Bytes(s->st_size);
152 }
153 
154 
156  const std::string& path,
158 {
159  Try<struct ::stat> s = internal::stat(path, follow);
160  if (s.isError()) {
161  return Error(s.error());
162  }
163 
164  return s->st_mtime;
165 }
166 
167 
169  const std::string& path,
171 {
172  Try<struct ::stat> s = internal::stat(path, follow);
173  if (s.isError()) {
174  return Error(s.error());
175  }
176 
177  return s->st_mode;
178 }
179 
180 
182  const std::string& path,
184 {
185  Try<struct ::stat> s = internal::stat(path, follow);
186  if (s.isError()) {
187  return Error(s.error());
188  }
189 
190  return s->st_dev;
191 }
192 
193 
195  const std::string& path,
197 {
198  Try<struct ::stat> s = internal::stat(path, follow);
199  if (s.isError()) {
200  return Error(s.error());
201  }
202 
203  if (!S_ISCHR(s->st_mode) && !S_ISBLK(s->st_mode)) {
204  return Error("Not a special file: " + path);
205  }
206 
207  return s->st_rdev;
208 }
209 
210 
212  const std::string& path,
214 {
215  Try<struct ::stat> s = internal::stat(path, follow);
216  if (s.isError()) {
217  return Error(s.error());
218  }
219 
220  return s->st_ino;
221 }
222 
223 
225  const std::string& path,
227 {
228  Try<struct ::stat> s = internal::stat(path, follow);
229  if (s.isError()) {
230  return Error(s.error());
231  }
232 
233  return s->st_uid;
234 }
235 
236 } // namespace stat {
237 
238 } // namespace os {
239 
240 #endif // __STOUT_OS_POSIX_STAT_HPP__
Definition: path.hpp:29
Try< uid_t > uid(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:224
bool isfile(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:108
Definition: errorbase.hpp:36
Try< Bytes > size(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:130
bool issocket(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:117
bool S_ISDIR(const int mode)
Definition: windows.hpp:200
bool islink(const std::string &path)
Definition: stat.hpp:80
Definition: check.hpp:33
bool S_ISSOCK(const int mode)
Definition: windows.hpp:230
bool S_ISREG(const int mode)
Definition: windows.hpp:206
Definition: errorbase.hpp:50
Try< long > mtime(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:155
Definition: posix_signalhandler.hpp:23
Try< ino_t > inode(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:211
FollowSymlink
Definition: reparsepoint.hpp:35
Try< dev_t > dev(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:181
Try< dev_t > rdev(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:194
bool isSome() const
Definition: try.hpp:77
Try< struct::stat > stat(const int_fd fd)
Definition: stat.hpp:68
bool S_ISBLK(const int mode)
Definition: windows.hpp:224
static Try error(const E &e)
Definition: try.hpp:43
#define UNREACHABLE()
Definition: unreachable.hpp:22
Definition: attributes.hpp:24
bool isError() const
Definition: try.hpp:78
bool isdir(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:91
bool S_ISLNK(const int mode)
Definition: windows.hpp:236
Try< mode_t > mode(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:168
bool S_ISCHR(const int mode)
Definition: windows.hpp:212
Definition: bytes.hpp:30
int int_fd
Definition: int_fd.hpp:35
Try< struct::stat > stat(const std::string &path, const FollowSymlink follow)
Definition: stat.hpp:45