From: Gerd von Egidy Date: Sun, 10 May 2015 14:56:29 +0000 (+0200) Subject: make pid_of work with processes owned by other users, same method used as in 'ps' X-Git-Tag: v2.7~1 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=edd749dea4ed4b0a7fd5432c1dbd2d3b997ac626;p=libi2ncommon make pid_of work with processes owned by other users, same method used as in 'ps' --- diff --git a/src/daemonfunc.cpp b/src/daemonfunc.cpp index ebeccfe..99f3be8 100644 --- a/src/daemonfunc.cpp +++ b/src/daemonfunc.cpp @@ -121,7 +121,10 @@ bool pid_of(const std::string& name, std::vector< pid_t >& result) std::vector< pid_t > fuzz1_result; std::vector< pid_t > fuzz2_result; result.clear(); + + if (name.empty()) return false; if (!get_dir("/proc", entries)) return false; + for (std::vector< std::string >::const_iterator it= entries.begin(); it != entries.end(); ++it) @@ -133,21 +136,49 @@ bool pid_of(const std::string& name, std::vector< pid_t >& result) I2n::Stat stat(exe_path, false); if (not stat or not stat.is_link()) continue; std::string real_exe= read_link(exe_path); - if (real_exe == name) + if (!real_exe.empty()) { - result.push_back( pid ); - continue; + // we got the path of the exe + if (real_exe == name) + { + result.push_back( pid ); + continue; + } + + std::string proc_stat= read_file( base_path + "/stat"); + if (proc_stat.empty()) continue; // process vanished + + //TODO some more fuzz tests here?! (cmdline, stat(us)) + + if (basename(real_exe) == name) + { + fuzz2_result.push_back(pid); + continue; + } } - - std::string proc_stat= read_file( base_path + "/stat"); - if (proc_stat.empty()) continue; // process vanished - - //TODO some more fuzz tests here?! (cmdline, stat(us)) - - if (basename(real_exe) == name) + else { - fuzz2_result.push_back(pid); - continue; + // we haven't got the path of the exe + // this can happen e.g. with processes owned by other users + // -> parse the commandline instead + std::string cmdline = read_file(base_path + "/cmdline"); + if (cmdline.empty()) continue; + + // in /proc/*/cmdline, the parameters are split by nullbytes, we only care for the first parameter + if (cmdline.find('\0') != string::npos) + cmdline.erase(cmdline.find('\0')); + + if (cmdline == name) + { + result.push_back( pid ); + continue; + } + + if (basename(cmdline) == name) + { + fuzz2_result.push_back(pid); + continue; + } } } if (result.empty())