Apache Mesos
lsof.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_LSOF_HPP__
14 #define __STOUT_OS_POSIX_LSOF_HPP__
15 
16 #include <string>
17 #include <vector>
18 
19 #include <stout/numify.hpp>
20 #include <stout/try.hpp>
21 
22 #include <stout/os/int_fd.hpp>
23 #include <stout/os/ls.hpp>
24 
25 namespace os {
26 
27 // Get all the open file descriptors of the current process.
29 {
30  int fdDir = ::open("/dev/fd", O_RDONLY | O_CLOEXEC);
31  if (fdDir == -1) {
32  return ErrnoError("Failed to open '/dev/fd'");
33  }
34 
35  DIR* dir = ::fdopendir(fdDir);
36  if (dir == nullptr) {
37  Error error = ErrnoError("Failed to fdopendir '/dev/fd'");
38  ::close(fdDir);
39  return error;
40  }
41 
42  struct dirent* entry;
43  std::vector<int_fd> result;
44 
45  // Zero `errno` before starting to call `readdir`. This is necessary
46  // to allow us to determine when `readdir` returns an error.
47  errno = 0;
48 
49  while ((entry = ::readdir(dir)) != nullptr) {
50  if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
51  continue;
52  }
53 
54  Try<int_fd> fd = numify<int_fd>(entry->d_name);
55  if (fd.isError()) {
56  return Error(
57  "Could not interpret file descriptor '" +
58  std::string(entry->d_name) + "': " + fd.error());
59  }
60 
61  if (fd.get() != fdDir) {
62  result.push_back(fd.get());
63  }
64  }
65 
66  if (errno != 0) {
67  // Preserve `readdir` error.
68  Error error = ErrnoError("Failed to read directory");
69  ::closedir(dir);
70  return error;
71  }
72 
73  if (::closedir(dir) == -1) {
74  return ErrnoError("Failed to close directory");
75  }
76 
77  return result;
78 }
79 
80 } // namespace os {
81 
82 #endif /* __STOUT_OS_POSIX_LSOF_HPP__ */
Definition: errorbase.hpp:36
T & get()&
Definition: try.hpp:80
Definition: check.hpp:33
Try< int_fd > open(const std::string &path, int oflag, mode_t mode=0)
Definition: open.hpp:35
Definition: errorbase.hpp:50
Definition: posix_signalhandler.hpp:23
constexpr int O_CLOEXEC
Definition: open.hpp:41
Try< Nothing > close(int fd)
Definition: close.hpp:24
static Try error(const E &e)
Definition: try.hpp:43
bool isError() const
Definition: try.hpp:78
std::string error(const std::string &msg, uint32_t code)
Try< std::vector< int_fd > > lsof()
Definition: lsof.hpp:28