Chromium Code Reviews| Index: base/linux_util.cc |
| diff --git a/base/linux_util.cc b/base/linux_util.cc |
| index 74ac98f7703653c94ae3f9e1314c0eaea49d4fac..3ff7e08e389cf79eeed44e02b1cabd5cbf6fc194 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,33 +156,18 @@ 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) { |
|
Avi (use Gerrit)
2016/09/16 22:26:29
for (pid_t tid : tids)
reveman
2016/09/16 23:06:41
Done
|
| const pid_t current_tid = *i; |
| + char buf[256]; |
| snprintf(buf, sizeof(buf), "/proc/%d/task/%d/syscall", pid, current_tid); |
| int fd = open(buf, O_RDONLY); |
| if (fd < 0) |
| @@ -178,4 +187,44 @@ pid_t FindThreadIDWithSyscall(pid_t pid, const std::string& expected_data, |
| 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 (std::vector<pid_t>::const_iterator i = tids.begin(); i != tids.end(); |
| + ++i) { |
|
Avi (use Gerrit)
2016/09/16 22:26:29
for (pid_t tid : tids)
reveman
2016/09/16 23:06:41
Done
|
| + const pid_t current_tid = *i; |
| + char buf[256]; |
| + snprintf(buf, sizeof(buf), "/proc/%d/task/%d/status", pid, current_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; |
| +} |
| + |
| } // namespace base |