/* This file is part of c++script. c++script is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. c++script is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with c++script. If not, see . */ #include #include #include #include #include "c++script.h" using namespace std; extern char **environ; namespace cpps{ static bool debug = false; void processes_debug() { debug = true; } static void selectnameval_cnv(std::string_view val, std::string &var) { var = val; } static void selectnameval_cnv(std::string_view val, auto &var) { std::from_chars(val.data(),val.data()+val.size(),var); } std::string string_trim(const std::string_view v) { string ret; for (auto c:v | views::drop_while([](auto c){return c == ' ' || c == '\t';}) | views::reverse | views::drop_while([](auto c){return c == ' ' || c == '\t' || c == '\n';}) | views::reverse){ ret += c; } return ret; } std::vector string_split (const std::string_view v, char delim) { std::vector ret; char delim2 = '\0'; if (delim == ' ') delim2 = '\t'; auto pt = v.begin(); auto start = pt; while (pt != v.end()){ if (*pt == delim || *pt == delim2){ if (pt != start) ret.emplace_back(start,pt); start = pt+1; } pt++; } if (pt != start) ret.emplace_back(start,pt); return ret; } auto selectnameval(std::string_view item, auto &var) { return views::filter([item,&var](auto &l){ bool ret = true; if (l.line.compare(0,item.size(),item)==0){ string tmp = string_trim(l.line.substr(item.size())); selectnameval_cnv(tmp,var); ret = false; } return ret; }); } PROCESS::PROCESS(string_view _pid) { int res=0; std::from_chars(_pid.data(),_pid.data()+_pid.size(),res); pid = res; ppid = 0; tgid = 0; uid = 0; gid = 0; vmsize=0; vmrss=0; char path[1000]; auto size = readlink(format("/proc/{}/exe",pid).c_str(),path,sizeof(path)-1); if (size > 0) exe = string(path,path+size); #if 0 FILENAME cmdline(format("/proc/{}/cmdline",pid)); for (auto w:cmdline.cat() | views::take(1) | views::transform([](auto &l) -> string {return l.line;}) | views::join | views::split('\0') | views::take(1)){ cerr << "cmdline " << w << "\n"; } #endif #if 1 FILENAME status(format("/proc/{}/status",pid)); for (auto w:status.cat() | selectnameval("Name:",name) | selectnameval("PPid:"sv,ppid) | selectnameval("Tgid:"sv,tgid) | selectnameval("Uid:",uid) | selectnameval("Gid:",gid) | selectnameval("VmSize:",vmsize) | selectnameval("VmRSS:",vmrss) ){ } #endif } bool PROCESS::is_kernel() const { return vmsize == 0 && vmrss == 0; } bool PROCESS::is_thread() const { return tgid != pid; } pid_t PROCESS::get_parent() const { return is_thread() ? tgid : ppid; } /* Turn all environnement variables into a map */ const std::map makeenviron() { map mp; char **pt = environ; while (*pt != nullptr){ const char *start = *pt; const char *pteq = strchr(start,'='); if (pteq != nullptr){ mp[string(start,pteq)] = (pteq+1); } pt++; } return mp; } }