1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "sandbox/linux/services/proc_util.h"
12 #include <sys/types.h>
14 #include "base/logging.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/posix/eintr_wrapper.h"
17 #include "base/strings/string_number_conversions.h"
23 void operator()(DIR* d
) const {
25 PCHECK(0 == closedir(d
));
29 typedef scoped_ptr
<DIR, DIRCloser
> ScopedDIR
;
31 base::ScopedFD
OpenDirectory(const char* path
) {
33 base::ScopedFD
directory_fd(
34 HANDLE_EINTR(open(path
, O_RDONLY
| O_DIRECTORY
| O_CLOEXEC
)));
35 PCHECK(directory_fd
.is_valid());
36 return directory_fd
.Pass();
41 int ProcUtil::CountOpenFds(int proc_fd
) {
42 DCHECK_LE(0, proc_fd
);
43 int proc_self_fd
= HANDLE_EINTR(
44 openat(proc_fd
, "self/fd/", O_DIRECTORY
| O_RDONLY
| O_CLOEXEC
));
45 PCHECK(0 <= proc_self_fd
);
47 // Ownership of proc_self_fd is transferred here, it must not be closed
48 // or modified afterwards except via dir.
49 ScopedDIR
dir(fdopendir(proc_self_fd
));
55 while (!readdir_r(dir
.get(), &e
, &de
) && de
) {
56 if (strcmp(e
.d_name
, ".") == 0 || strcmp(e
.d_name
, "..") == 0) {
61 CHECK(base::StringToInt(e
.d_name
, &fd_num
));
62 if (fd_num
== proc_fd
|| fd_num
== proc_self_fd
) {
71 bool ProcUtil::HasOpenDirectory(int proc_fd
) {
72 DCHECK_LE(0, proc_fd
);
74 openat(proc_fd
, "self/fd/", O_DIRECTORY
| O_RDONLY
| O_CLOEXEC
);
76 PCHECK(0 <= proc_self_fd
);
78 // Ownership of proc_self_fd is transferred here, it must not be closed
79 // or modified afterwards except via dir.
80 ScopedDIR
dir(fdopendir(proc_self_fd
));
85 while (!readdir_r(dir
.get(), &e
, &de
) && de
) {
86 if (strcmp(e
.d_name
, ".") == 0 || strcmp(e
.d_name
, "..") == 0) {
91 CHECK(base::StringToInt(e
.d_name
, &fd_num
));
92 if (fd_num
== proc_fd
|| fd_num
== proc_self_fd
) {
97 // It's OK to use proc_self_fd here, fstatat won't modify it.
98 CHECK(fstatat(proc_self_fd
, e
.d_name
, &s
, 0) == 0);
99 if (S_ISDIR(s
.st_mode
)) {
104 // No open unmanaged directories found.
108 bool ProcUtil::HasOpenDirectory() {
109 base::ScopedFD
proc_fd(
110 HANDLE_EINTR(open("/proc/", O_DIRECTORY
| O_RDONLY
| O_CLOEXEC
)));
111 return HasOpenDirectory(proc_fd
.get());
115 base::ScopedFD
ProcUtil::OpenProc() {
116 return OpenDirectory("/proc/");
119 } // namespace sandbox