summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--debian/changelog6
-rw-r--r--process.cpp43
-rw-r--r--process.h2
-rw-r--r--tests/test-process.cpp12
4 files changed, 53 insertions, 10 deletions
diff --git a/debian/changelog b/debian/changelog
index 2f91dac..8f473aa 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+libreichwein (1.4~pre1) UNRELEASED; urgency=medium
+
+ * Added number_of_threads()
+
+ -- Roland Reichwein <mail@reichwein.it> Sun, 05 Feb 2023 00:25:04 +0100
+
libreichwein (1.3) unstable; urgency=medium
* Fixed upload in Makefile
diff --git a/process.cpp b/process.cpp
index 67cf1ce..c504330 100644
--- a/process.cpp
+++ b/process.cpp
@@ -16,23 +16,48 @@ namespace fs = std::filesystem;
bool Reichwein::Process::is_running(pid_t pid)
{
- fs::path pid_file{"/proc/" + std::to_string(pid) + "/stat"};
- if (!fs::exists(pid_file))
- return false;
+ // 3rd position is status for pid
+ fs::path pid_file{"/proc/" + std::to_string(pid) + "/stat"};
+ if (!fs::exists(pid_file))
+ return false;
- std::string s{Reichwein::File::getFile(pid_file)};
+ std::string s{Reichwein::File::getFile(pid_file)};
- auto pos0{s.find(' ', 0)};
+ auto pos0{s.find(' ', 0)};
+ pos0 = s.find(' ', pos0 + 1);
+ pos0++;
+
+ auto pos1{s.find(' ', pos0 + 1)};
+
+ std::string state{s.substr(pos0, pos1 - pos0)};
+
+ return state == "R" || state == "S";
+}
+
+int Reichwein::Process::number_of_threads(pid_t pid)
+{
+ // 20th position is the number of threads for pid
+ fs::path pid_file{"/proc/" + std::to_string(pid) + "/stat"};
+ if (!fs::exists(pid_file))
+ return false;
+
+ std::string s{Reichwein::File::getFile(pid_file)};
+
+ size_t pos0{};
+ for (int i = 0; i < 19; i++) {
pos0 = s.find(' ', pos0 + 1);
- pos0++;
+ if (pos0 == std::string::npos)
+ throw std::runtime_error("Bad format in /proc/" + std::to_string(pid) + "/stat");
+ }
- auto pos1{s.find(' ', pos0 + 1)};
+ size_t pos1{s.find(' ', pos0 + 1)};
- std::string state{s.substr(pos0, pos1 - pos0)};
+ std::string number_of_threads_s{s.substr(pos0, pos1 - pos0)};
- return state == "R" || state == "S";
+ return std::stoi(number_of_threads_s);
}
+
// tcp: tcp or tcp6
bool Reichwein::Process::tcp_is_pid_listening_on(const std::string& tcp, pid_t pid, int port)
{
diff --git a/process.h b/process.h
index fb24017..b01778c 100644
--- a/process.h
+++ b/process.h
@@ -10,6 +10,8 @@ namespace Reichwein::Process {
EXPORT bool is_running(pid_t pid);
+EXPORT int number_of_threads(pid_t pid);
+
EXPORT bool unix_is_pid_listening_on(pid_t pid, const std::string& path);
EXPORT void wait_for_pid_listening_on(pid_t pid, const std::string& path);
diff --git a/tests/test-process.cpp b/tests/test-process.cpp
index dfee83f..9855546 100644
--- a/tests/test-process.cpp
+++ b/tests/test-process.cpp
@@ -1,5 +1,7 @@
#include <gtest/gtest.h>
+#include <thread>
+
#include "process.h"
#include <unistd.h>
@@ -23,7 +25,7 @@ protected:
};
-TEST_F(ProcessTest,is_running) {
+TEST_F(ProcessTest, is_running) {
auto pid{::getpid()};
EXPECT_NE(pid, -1);
@@ -32,3 +34,11 @@ TEST_F(ProcessTest,is_running) {
EXPECT_EQ(Reichwein::Process::is_running(999999999), false);
}
+
+TEST_F(ProcessTest, number_of_threads) {
+ EXPECT_EQ(Reichwein::Process::number_of_threads(::getpid()), 1);
+ std::thread t1{[](){std::this_thread::sleep_for(std::chrono::milliseconds(50));}};
+ EXPECT_EQ(Reichwein::Process::number_of_threads(::getpid()), 2);
+ t1.join();
+ EXPECT_EQ(Reichwein::Process::number_of_threads(::getpid()), 1);
+}