Merge "profiling: Simplify code to find pids."
diff --git a/src/profiling/memory/heapprofd_producer.cc b/src/profiling/memory/heapprofd_producer.cc
index 5ab9015..e07a644 100644
--- a/src/profiling/memory/heapprofd_producer.cc
+++ b/src/profiling/memory/heapprofd_producer.cc
@@ -46,7 +46,8 @@
   return client_config;
 }
 
-void FindAllProfilablePids(std::vector<pid_t>* pids) {
+template <typename Fn>
+void ForEachPid(const char* file, Fn callback) {
   base::ScopedDir proc_dir(opendir("/proc"));
   if (!proc_dir) {
     PERFETTO_DFATAL("Failed to open /proc");
@@ -56,7 +57,7 @@
   while ((entry = readdir(*proc_dir))) {
     char filename_buf[128];
     ssize_t written = snprintf(filename_buf, sizeof(filename_buf),
-                               "/proc/%s/cmdline", entry->d_name);
+                               "/proc/%s/%s", entry->d_name, file);
     if (written < 0 || static_cast<size_t>(written) >= sizeof(filename_buf)) {
       if (written < 0)
         PERFETTO_DFATAL("Failed to concatenate cmdline file.");
@@ -64,63 +65,51 @@
         PERFETTO_DFATAL("Overflow when concatenating cmdline file.");
       continue;
     }
+    char* end;
+    long int pid = strtol(entry->d_name, &end, 10);
+    if (*end != '\0')
+      continue;
+    callback(static_cast<pid_t>(pid), filename_buf);
+  }
+}
 
+void FindAllProfilablePids(std::vector<pid_t>* pids) {
+  ForEachPid("cmdline", [pids](pid_t pid, const char* filename_buf) {
+    if (pid == getpid())
+      return;
     struct stat statbuf;
     // Check if we have permission to the process.
-    if (stat(filename_buf, &statbuf) == 0) {
-      char* end;
-      long int pid = strtol(entry->d_name, &end, 10);
-      if (*end != '\0')
-        continue;
-      if (pid != getpid())
-        pids->emplace_back(pid);
-    }
-  }
+    if (stat(filename_buf, &statbuf) == 0)
+      pids->emplace_back(pid);
+  });
 }
 
 void FindPidsForCmdlines(const std::vector<std::string>& cmdlines,
                          std::vector<pid_t>* pids) {
-  base::ScopedDir proc_dir(opendir("/proc"));
-  if (!proc_dir) {
-    PERFETTO_DFATAL("Failed to open /proc");
-    return;
-  }
-  struct dirent* entry;
-  while ((entry = readdir(*proc_dir))) {
-    char* end;
-    long int pid = strtol(entry->d_name, &end, 10);
-    if (*end != '\0') {
-      continue;
-    }
-
-    char filename_buf[128];
-
-    if (snprintf(filename_buf, sizeof(filename_buf), "/proc/%lu/cmdline", pid) <
-        0) {
-      PERFETTO_DFATAL("Failed to create comm filename for %lu", pid);
-      continue;
-    }
+  ForEachPid("cmdline", [&cmdlines, pids](pid_t pid, const char* filename_buf) {
+    if (pid == getpid())
+      return;
     std::string process_cmdline;
     process_cmdline.reserve(128);
     if (!base::ReadFile(filename_buf, &process_cmdline))
-      continue;
+      return;
     if (process_cmdline.empty())
-      continue;
+      return;
 
     // Strip everything after @ for Java processes.
     // Otherwise, strip newline at EOF.
-    size_t endpos = process_cmdline.find('\0');
+    size_t endpos = process_cmdline.find('@');
     if (endpos == std::string::npos)
-      continue;
+      endpos = process_cmdline.size();
     if (endpos < 1)
-      continue;
+      return;
     process_cmdline.resize(endpos);
 
     for (const std::string& cmdline : cmdlines) {
       if (process_cmdline == cmdline)
         pids->emplace_back(static_cast<pid_t>(pid));
     }
-  }
+  });
 }
 
 }  // namespace