diff --git a/LibCore/CProcessStatisticsReader.cpp b/LibCore/CProcessStatisticsReader.cpp new file mode 100644 index 0000000000..1a80f306c3 --- /dev/null +++ b/LibCore/CProcessStatisticsReader.cpp @@ -0,0 +1,100 @@ +#include "CProcessStatisticsReader.h" +#include "CFile.h" + +#include +#include + +CProcessStatisticsReader::CProcessStatisticsReader() +{ + setpwent(); + while (auto* passwd = getpwent()) + m_usernames.set(passwd->pw_uid, passwd->pw_name); + endpwent(); +} + +HashMap CProcessStatisticsReader::get_map() +{ + HashMap res; + update_map(res); + return res; +} + +void CProcessStatisticsReader::update_map(HashMap& map) +{ + CFile file("/proc/all"); + if (!file.open(CIODevice::ReadOnly)) { + fprintf(stderr, "CProcessHelper : failed to open /proc/all: %s\n", file.error_string()); + return; + } + + for (;;) { + auto line = file.read_line(1024); + + if (line.is_empty()) + break; + + auto chomped = String((const char*)line.pointer(), line.size() - 1, Chomp); + auto parts = chomped.split_view(','); + + if (parts.size() < 18) + break; + + bool ok = false; + CProcessStatistics process; + + process.pid = parts[0].to_uint(ok); + if (!ok) { + fprintf(stderr, "CProcessHelper : couldn't convert %s to a valid pid\n", parts[0].characters()); + return; + } + + process.nsched = parts[1].to_uint(ok); + if (!ok) { + fprintf(stderr, "CProcessHelper : couldn't convert %s to a valid nsched value\n", parts[1].characters()); + return; + } + + uid_t uid = parts[5].to_uint(ok); + if (!ok) { + fprintf(stderr, "CProcessHelper : couldn't convert %s to a valid uid value\n", parts[5].characters()); + return; + } + + process.uid = uid; + process.username = get_username_from_uid(uid); + + process.priority = parts[16]; + + process.syscalls = parts[17].to_uint(ok); + if (!ok) { + fprintf(stderr, "CProcessHelper : couldn't convert %s to a valid syscalls count value\n", parts[17].characters()); + return; + } + + process.state = parts[7]; + + process.name = parts[11]; + process.linear = parts[12].to_uint(ok); + if (!ok) { + fprintf(stderr, "CProcessHelper : couldn't convert %s to a valid amount of linear address space used\n", parts[12].characters()); + return; + } + + process.physical = parts[13].to_uint(ok); + if (!ok) { + fprintf(stderr, "CProcessHelper : couldn't convert %s to a valid amount of physical address space used\n", parts[13].characters()); + return; + } + + map.set(process.pid, process); + } +} + +String CProcessStatisticsReader::get_username_from_uid(const uid_t uid) +{ + auto it = m_usernames.find(uid); + if (it != m_usernames.end()) + return (*it).value; + else + return String::format("%u", uid); +} diff --git a/LibCore/CProcessStatisticsReader.h b/LibCore/CProcessStatisticsReader.h new file mode 100644 index 0000000000..2ce97e9f68 --- /dev/null +++ b/LibCore/CProcessStatisticsReader.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +struct CProcessStatistics { + pid_t pid; + unsigned nsched; + String name; + String state; + String username; + uid_t uid; + String priority; + size_t linear; + size_t physical; + unsigned syscalls; +}; + +class CProcessStatisticsReader { +public: + CProcessStatisticsReader(); + HashMap get_map(); + +private: + void update_map(HashMap& map); + String get_username_from_uid(const uid_t uid); + + HashMap m_usernames; +}; diff --git a/LibCore/Makefile b/LibCore/Makefile index 710a77ae65..a8a7fb00d6 100644 --- a/LibCore/Makefile +++ b/LibCore/Makefile @@ -16,7 +16,8 @@ OBJS = \ CTimer.o \ CEventLoop.o \ CConfigFile.o \ - CEvent.o + CEvent.o \ + CProcessStatisticsReader.o LIBRARY = libcore.a DEFINES += -DUSERLAND diff --git a/Userland/killall.cpp b/Userland/killall.cpp index cd28a6a56b..11413511a9 100644 --- a/Userland/killall.cpp +++ b/Userland/killall.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include static void print_usage_and_exit() @@ -13,40 +13,16 @@ static void print_usage_and_exit() static int kill_all(const String& process_name, const unsigned signum) { - CFile file("/proc/all"); - if (!file.open(CIODevice::ReadOnly)) { - fprintf(stderr, "killall failed to open /proc/all\n"); - return 3; + HashMap processes = CProcessStatisticsReader().get_map(); + + for (auto& it : processes) { + if (it.value.name == process_name) { + int ret = kill(it.value.pid, signum); + if (ret < 0) + perror("kill"); + } } - - for (;;) { - auto line = file.read_line(1024); - - if (line.is_empty()) - break; - - auto chomped = String((const char*)line.pointer(), line.size() - 1, Chomp); - auto parts = chomped.split_view(','); - - if (parts.size() < 18) - break; - - bool ok = false; - pid_t pid = parts[0].to_uint(ok); - String name = parts[11]; - - if (!ok) { - fprintf(stderr, "killall failed : couldn't convert %s to a valid pid\n", parts[0].characters()); - return 4; - } - - if (name == process_name) { - int ret = kill(pid, signum); - if (ret < 0) - perror("kill"); - } - } - + return 0; } @@ -60,12 +36,12 @@ int main(int argc, char** argv) print_usage_and_exit(); if (argc == 3) { - name_argi = 2; - + name_argi = 2; + if (argv[1][0] != '-') print_usage_and_exit(); - - signum = String(&argv[1][1]).to_uint(ok); + + signum = String(&argv[1][1]).to_uint(ok); if (!ok) { printf("'%s' is not a valid signal number\n", &argv[1][1]); return 2; diff --git a/Userland/pidof.cpp b/Userland/pidof.cpp index ab15a05417..833930464c 100644 --- a/Userland/pidof.cpp +++ b/Userland/pidof.cpp @@ -2,55 +2,32 @@ #include #include #include -#include +#include #include #include #include +#include static int pid_of(const String& process_name, bool single_shot, bool omit_pid, pid_t pid) { bool displayed_at_least_one = false; - CFile file("/proc/all"); - if (!file.open(CIODevice::ReadOnly)) { - fprintf(stderr, "pidof failed to open /proc/all\n"); - return 2; - } + HashMap processes = CProcessStatisticsReader().get_map(); + + for (auto& it : processes) { + if (it.value.name == process_name) { + if (!omit_pid || (omit_pid && it.value.pid != pid)) { + printf("%d ", it.value.pid); + displayed_at_least_one = true; - for (;;) { - auto line = file.read_line(1024); - - if (line.is_empty()) - break; - - auto chomped = String((const char*)line.pointer(), line.size() - 1, Chomp); - auto parts = chomped.split_view(','); - - if (parts.size() < 18) - break; - - bool ok = false; - pid_t current_pid = parts[0].to_uint(ok); - String name = parts[11]; - - if (!ok) { - fprintf(stderr, "pidof failed : couldn't convert %s to a valid pid\n", parts[0].characters()); - return 3; - } - - if (name == process_name) { - if (!omit_pid || (omit_pid && current_pid != pid)) { - printf("%d ", current_pid); - displayed_at_least_one = true; - - if (single_shot) - break; - } - } + if (single_shot) + break; + } + } } if (displayed_at_least_one) - printf("\n"); + printf("\n"); return 0; } @@ -72,16 +49,16 @@ int main(int argc, char** argv) bool ok = false; String pid_str = args.get("o"); - if (pid_str == "%PPID") - pid = getppid(); - else - pid = pid_str.to_uint(ok); + if (pid_str == "%PPID") + pid = getppid(); + else + pid = pid_str.to_uint(ok); } // We should have one single value : the process name Vector values = args.get_single_values(); if (values.size() == 0) { - args_parser.print_usage(); + args_parser.print_usage(); return 0; }