Merge "Add android::base::GetPids() function to return all pids"
diff --git a/base/Android.bp b/base/Android.bp
index 58b6fb5..357ce01 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -53,6 +53,7 @@
         "logging.cpp",
         "mapped_file.cpp",
         "parsenetaddress.cpp",
+        "process.cpp",
         "properties.cpp",
         "quick_exit.cpp",
         "stringprintf.cpp",
@@ -145,6 +146,7 @@
         "parsedouble_test.cpp",
         "parseint_test.cpp",
         "parsenetaddress_test.cpp",
+        "process_test.cpp",
         "properties_test.cpp",
         "quick_exit_test.cpp",
         "result_test.cpp",
diff --git a/base/include/android-base/process.h b/base/include/android-base/process.h
new file mode 100644
index 0000000..69ed3fb
--- /dev/null
+++ b/base/include/android-base/process.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <dirent.h>
+#include <sys/types.h>
+
+#include <iterator>
+#include <memory>
+#include <vector>
+
+namespace android {
+namespace base {
+
+class AllPids {
+  class PidIterator {
+   public:
+    PidIterator(DIR* dir) : dir_(dir, closedir) { Increment(); }
+    PidIterator& operator++() {
+      Increment();
+      return *this;
+    }
+    bool operator==(const PidIterator& other) const { return pid_ == other.pid_; }
+    bool operator!=(const PidIterator& other) const { return !(*this == other); }
+    long operator*() const { return pid_; }
+    // iterator traits
+    using difference_type = pid_t;
+    using value_type = pid_t;
+    using pointer = const pid_t*;
+    using reference = const pid_t&;
+    using iterator_category = std::input_iterator_tag;
+
+   private:
+    void Increment();
+
+    pid_t pid_ = -1;
+    std::unique_ptr<DIR, decltype(&closedir)> dir_;
+  };
+
+ public:
+  PidIterator begin() { return opendir("/proc"); }
+  PidIterator end() { return nullptr; }
+};
+
+}  // namespace base
+}  // namespace android
diff --git a/base/process.cpp b/base/process.cpp
new file mode 100644
index 0000000..b8cabf6
--- /dev/null
+++ b/base/process.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "android-base/process.h"
+
+namespace android {
+namespace base {
+
+void AllPids::PidIterator::Increment() {
+  if (!dir_) {
+    return;
+  }
+
+  dirent* de;
+  while ((de = readdir(dir_.get())) != nullptr) {
+    pid_t pid = atoi(de->d_name);
+    if (pid != 0) {
+      pid_ = pid;
+      return;
+    }
+  }
+  pid_ = -1;
+}
+
+}  // namespace base
+}  // namespace android
diff --git a/base/process_test.cpp b/base/process_test.cpp
new file mode 100644
index 0000000..056f667
--- /dev/null
+++ b/base/process_test.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "android-base/process.h"
+
+#include <unistd.h>
+
+#include <gtest/gtest.h>
+
+TEST(process, find_ourselves) {
+#if defined(__linux__)
+  bool found_our_pid = false;
+  for (const auto& pid : android::base::AllPids{}) {
+    if (pid == getpid()) {
+      found_our_pid = true;
+    }
+  }
+
+  EXPECT_TRUE(found_our_pid);
+
+#endif
+}