summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libprocinfo/include/procinfo/process.h26
-rw-r--r--libprocinfo/process.cpp18
2 files changed, 29 insertions, 15 deletions
diff --git a/libprocinfo/include/procinfo/process.h b/libprocinfo/include/procinfo/process.h
index db56fc1a5..9278e1819 100644
--- a/libprocinfo/include/procinfo/process.h
+++ b/libprocinfo/include/procinfo/process.h
@@ -56,23 +56,25 @@ struct ProcessInfo {
56}; 56};
57 57
58// Parse the contents of /proc/<tid>/status into |process_info|. 58// Parse the contents of /proc/<tid>/status into |process_info|.
59bool GetProcessInfo(pid_t tid, ProcessInfo* process_info); 59bool GetProcessInfo(pid_t tid, ProcessInfo* process_info, std::string* error = nullptr);
60 60
61// Parse the contents of <fd>/status into |process_info|. 61// Parse the contents of <fd>/status into |process_info|.
62// |fd| should be an fd pointing at a /proc/<pid> directory. 62// |fd| should be an fd pointing at a /proc/<pid> directory.
63bool GetProcessInfoFromProcPidFd(int fd, ProcessInfo* process_info); 63bool GetProcessInfoFromProcPidFd(int fd, ProcessInfo* process_info, std::string* error = nullptr);
64 64
65// Fetch the list of threads from a given process's /proc/<pid> directory. 65// Fetch the list of threads from a given process's /proc/<pid> directory.
66// |fd| should be an fd pointing at a /proc/<pid> directory. 66// |fd| should be an fd pointing at a /proc/<pid> directory.
67template <typename Collection> 67template <typename Collection>
68auto GetProcessTidsFromProcPidFd(int fd, Collection* out) -> 68auto GetProcessTidsFromProcPidFd(int fd, Collection* out, std::string* error = nullptr) ->
69 typename std::enable_if<sizeof(typename Collection::value_type) >= sizeof(pid_t), bool>::type { 69 typename std::enable_if<sizeof(typename Collection::value_type) >= sizeof(pid_t), bool>::type {
70 out->clear(); 70 out->clear();
71 71
72 int task_fd = openat(fd, "task", O_DIRECTORY | O_RDONLY | O_CLOEXEC); 72 int task_fd = openat(fd, "task", O_DIRECTORY | O_RDONLY | O_CLOEXEC);
73 std::unique_ptr<DIR, int (*)(DIR*)> dir(fdopendir(task_fd), closedir); 73 std::unique_ptr<DIR, int (*)(DIR*)> dir(fdopendir(task_fd), closedir);
74 if (!dir) { 74 if (!dir) {
75 PLOG(ERROR) << "failed to open task directory"; 75 if (error != nullptr) {
76 *error = "failed to open task directory";
77 }
76 return false; 78 return false;
77 } 79 }
78 80
@@ -81,7 +83,9 @@ auto GetProcessTidsFromProcPidFd(int fd, Collection* out) ->
81 if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0) { 83 if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0) {
82 pid_t tid; 84 pid_t tid;
83 if (!android::base::ParseInt(dent->d_name, &tid, 1, std::numeric_limits<pid_t>::max())) { 85 if (!android::base::ParseInt(dent->d_name, &tid, 1, std::numeric_limits<pid_t>::max())) {
84 LOG(ERROR) << "failed to parse task id: " << dent->d_name; 86 if (error != nullptr) {
87 *error = std::string("failed to parse task id: ") + dent->d_name;
88 }
85 return false; 89 return false;
86 } 90 }
87 91
@@ -93,21 +97,25 @@ auto GetProcessTidsFromProcPidFd(int fd, Collection* out) ->
93} 97}
94 98
95template <typename Collection> 99template <typename Collection>
96auto GetProcessTids(pid_t pid, Collection* out) -> 100auto GetProcessTids(pid_t pid, Collection* out, std::string* error = nullptr) ->
97 typename std::enable_if<sizeof(typename Collection::value_type) >= sizeof(pid_t), bool>::type { 101 typename std::enable_if<sizeof(typename Collection::value_type) >= sizeof(pid_t), bool>::type {
98 char task_path[PATH_MAX]; 102 char task_path[PATH_MAX];
99 if (snprintf(task_path, PATH_MAX, "/proc/%d", pid) >= PATH_MAX) { 103 if (snprintf(task_path, PATH_MAX, "/proc/%d", pid) >= PATH_MAX) {
100 LOG(ERROR) << "task path overflow (pid = " << pid << ")"; 104 if (error != nullptr) {
105 *error = "task path overflow (pid = " + std::to_string(pid) + ")";
106 }
101 return false; 107 return false;
102 } 108 }
103 109
104 android::base::unique_fd fd(open(task_path, O_DIRECTORY | O_RDONLY | O_CLOEXEC)); 110 android::base::unique_fd fd(open(task_path, O_DIRECTORY | O_RDONLY | O_CLOEXEC));
105 if (fd == -1) { 111 if (fd == -1) {
106 PLOG(ERROR) << "failed to open " << task_path; 112 if (error != nullptr) {
113 *error = std::string("failed to open ") + task_path;
114 }
107 return false; 115 return false;
108 } 116 }
109 117
110 return GetProcessTidsFromProcPidFd(fd.get(), out); 118 return GetProcessTidsFromProcPidFd(fd.get(), out, error);
111} 119}
112 120
113#endif 121#endif
diff --git a/libprocinfo/process.cpp b/libprocinfo/process.cpp
index 6e5be6e56..9194cf3d0 100644
--- a/libprocinfo/process.cpp
+++ b/libprocinfo/process.cpp
@@ -31,17 +31,19 @@ using android::base::unique_fd;
31namespace android { 31namespace android {
32namespace procinfo { 32namespace procinfo {
33 33
34bool GetProcessInfo(pid_t tid, ProcessInfo* process_info) { 34bool GetProcessInfo(pid_t tid, ProcessInfo* process_info, std::string* error) {
35 char path[PATH_MAX]; 35 char path[PATH_MAX];
36 snprintf(path, sizeof(path), "/proc/%d", tid); 36 snprintf(path, sizeof(path), "/proc/%d", tid);
37 37
38 unique_fd dirfd(open(path, O_DIRECTORY | O_RDONLY)); 38 unique_fd dirfd(open(path, O_DIRECTORY | O_RDONLY));
39 if (dirfd == -1) { 39 if (dirfd == -1) {
40 PLOG(ERROR) << "failed to open " << path; 40 if (error != nullptr) {
41 *error = std::string("failed to open ") + path;
42 }
41 return false; 43 return false;
42 } 44 }
43 45
44 return GetProcessInfoFromProcPidFd(dirfd.get(), process_info); 46 return GetProcessInfoFromProcPidFd(dirfd.get(), process_info, error);
45} 47}
46 48
47static ProcessState parse_state(const char* state) { 49static ProcessState parse_state(const char* state) {
@@ -62,17 +64,21 @@ static ProcessState parse_state(const char* state) {
62 } 64 }
63} 65}
64 66
65bool GetProcessInfoFromProcPidFd(int fd, ProcessInfo* process_info) { 67bool GetProcessInfoFromProcPidFd(int fd, ProcessInfo* process_info, std::string* error) {
66 int status_fd = openat(fd, "status", O_RDONLY | O_CLOEXEC); 68 int status_fd = openat(fd, "status", O_RDONLY | O_CLOEXEC);
67 69
68 if (status_fd == -1) { 70 if (status_fd == -1) {
69 PLOG(ERROR) << "failed to open status fd in GetProcessInfoFromProcPidFd"; 71 if (error != nullptr) {
72 *error = "failed to open status fd in GetProcessInfoFromProcPidFd";
73 }
70 return false; 74 return false;
71 } 75 }
72 76
73 std::unique_ptr<FILE, decltype(&fclose)> fp(fdopen(status_fd, "r"), fclose); 77 std::unique_ptr<FILE, decltype(&fclose)> fp(fdopen(status_fd, "r"), fclose);
74 if (!fp) { 78 if (!fp) {
75 PLOG(ERROR) << "failed to open status file in GetProcessInfoFromProcPidFd"; 79 if (error != nullptr) {
80 *error = "failed to open status file in GetProcessInfoFromProcPidFd";
81 }
76 close(status_fd); 82 close(status_fd);
77 return false; 83 return false;
78 } 84 }