| Index: base/linux_util.cc
|
| diff --git a/base/linux_util.cc b/base/linux_util.cc
|
| index 74ac98f7703653c94ae3f9e1314c0eaea49d4fac..bf504718f06f2accdfb9656c8714a5ba6c536e9f 100644
|
| --- a/base/linux_util.cc
|
| +++ b/base/linux_util.cc
|
| @@ -20,6 +20,8 @@
|
| #include "base/files/file_util.h"
|
| #include "base/memory/singleton.h"
|
| #include "base/process/launch.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| +#include "base/strings/string_split.h"
|
| #include "base/strings/string_util.h"
|
| #include "base/synchronization/lock.h"
|
| #include "build/build_config.h"
|
| @@ -72,6 +74,28 @@ class LinuxDistroHelper {
|
| };
|
| #endif // if defined(OS_LINUX)
|
|
|
| +bool GetTasksForProcess(pid_t pid, std::vector<pid_t>* tids) {
|
| + char buf[256];
|
| + snprintf(buf, sizeof(buf), "/proc/%d/task", pid);
|
| +
|
| + DIR* task = opendir(buf);
|
| + if (!task) {
|
| + DLOG(WARNING) << "Cannot open " << buf;
|
| + return false;
|
| + }
|
| +
|
| + struct dirent* dent;
|
| + while ((dent = readdir(task))) {
|
| + char* endptr;
|
| + const unsigned long int tid_ul = strtoul(dent->d_name, &endptr, 10);
|
| + if (tid_ul == ULONG_MAX || *endptr)
|
| + continue;
|
| + tids->push_back(tid_ul);
|
| + }
|
| + closedir(task);
|
| + return true;
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace base {
|
| @@ -132,34 +156,17 @@ void SetLinuxDistro(const std::string& distro) {
|
|
|
| pid_t FindThreadIDWithSyscall(pid_t pid, const std::string& expected_data,
|
| bool* syscall_supported) {
|
| - char buf[256];
|
| - snprintf(buf, sizeof(buf), "/proc/%d/task", pid);
|
| -
|
| if (syscall_supported != NULL)
|
| *syscall_supported = false;
|
|
|
| - DIR* task = opendir(buf);
|
| - if (!task) {
|
| - DLOG(WARNING) << "Cannot open " << buf;
|
| - return -1;
|
| - }
|
| -
|
| std::vector<pid_t> tids;
|
| - struct dirent* dent;
|
| - while ((dent = readdir(task))) {
|
| - char* endptr;
|
| - const unsigned long int tid_ul = strtoul(dent->d_name, &endptr, 10);
|
| - if (tid_ul == ULONG_MAX || *endptr)
|
| - continue;
|
| - tids.push_back(tid_ul);
|
| - }
|
| - closedir(task);
|
| + if (!GetTasksForProcess(pid, &tids))
|
| + return -1;
|
|
|
| std::unique_ptr<char[]> syscall_data(new char[expected_data.length()]);
|
| - for (std::vector<pid_t>::const_iterator
|
| - i = tids.begin(); i != tids.end(); ++i) {
|
| - const pid_t current_tid = *i;
|
| - snprintf(buf, sizeof(buf), "/proc/%d/task/%d/syscall", pid, current_tid);
|
| + for (pid_t tid : tids) {
|
| + char buf[256];
|
| + snprintf(buf, sizeof(buf), "/proc/%d/task/%d/syscall", pid, tid);
|
| int fd = open(buf, O_RDONLY);
|
| if (fd < 0)
|
| continue;
|
| @@ -172,7 +179,45 @@ pid_t FindThreadIDWithSyscall(pid_t pid, const std::string& expected_data,
|
|
|
| if (0 == strncmp(expected_data.c_str(), syscall_data.get(),
|
| expected_data.length())) {
|
| - return current_tid;
|
| + return tid;
|
| + }
|
| + }
|
| + return -1;
|
| +}
|
| +
|
| +pid_t FindThreadID(pid_t pid, pid_t ns_tid, bool* ns_pid_supported) {
|
| + if (ns_pid_supported)
|
| + *ns_pid_supported = false;
|
| +
|
| + std::vector<pid_t> tids;
|
| + if (!GetTasksForProcess(pid, &tids))
|
| + return -1;
|
| +
|
| + for (pid_t tid : tids) {
|
| + char buf[256];
|
| + snprintf(buf, sizeof(buf), "/proc/%d/task/%d/status", pid, tid);
|
| + std::string status;
|
| + if (!ReadFileToString(FilePath(buf), &status))
|
| + return -1;
|
| + StringPairs pairs;
|
| + SplitStringIntoKeyValuePairs(status, ':', '\n', &pairs);
|
| + for (const auto& pair : pairs) {
|
| + const std::string& key = pair.first;
|
| + const std::string& value_str = pair.second;
|
| + if (key == "NSpid") {
|
| + if (ns_pid_supported)
|
| + *ns_pid_supported = true;
|
| + std::vector<StringPiece> split_value_str = SplitStringPiece(
|
| + value_str, "\t", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
|
| + DCHECK_NE(split_value_str.size(), 0u);
|
| + int value;
|
| + // The last value in the list is the PID in the namespace.
|
| + if (StringToInt(split_value_str.back(), &value) && value == ns_tid) {
|
| + // The first value in the list is the real PID.
|
| + if (StringToInt(split_value_str.front(), &value))
|
| + return value;
|
| + }
|
| + }
|
| }
|
| }
|
| return -1;
|
|
|