From: Sangwan Kwon Date: Mon, 24 Feb 2020 07:03:13 +0000 (+0900) Subject: Get process identifier from cmdline X-Git-Tag: submit/tizen/20200810.073515~70 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f1b6d41b4b24d746f4f9335b0edbfdaca8f96ee3;p=platform%2Fcore%2Fsecurity%2Fvist.git Get process identifier from cmdline Signed-off-by: Sangwan Kwon --- diff --git a/src/vist/process.hpp b/src/vist/process.hpp index b17bd1e..29e4ebc 100644 --- a/src/vist/process.hpp +++ b/src/vist/process.hpp @@ -17,7 +17,10 @@ #pragma once #include +#include +#include +#include #include #include #include @@ -26,6 +29,7 @@ #include #include #include +#include namespace vist { @@ -35,17 +39,45 @@ struct Process { return ::getpid(); } + /// TODO(Sangwan): Unify the method which get process identifier static std::string GetPath(pid_t pid) { - std::string cmdline = "/proc/" + std::to_string(pid) + "/exe"; + std::string exe = "/proc/" + std::to_string(pid) + "/exe"; /// c++17 std::filesystem::read_symlink std::vector buf(1024); - auto size = ::readlink(cmdline.c_str(), buf.data(), buf.size()); - if (size == -1) - THROW(ErrCode::RuntimeError) << "Failed to get process path: " << errno; + errno = 0; + auto size = ::readlink(exe.c_str(), buf.data(), buf.size()); + if (size == -1) { + WARN(VIST) << "Failed to get process path by exe: " << exe + << ", errno: " << errno; - return std::string(buf.begin(), buf.begin() + size); + std::string cmdline = "/proc/" + std::to_string(pid) + "/cmdline"; + int fd = ::open(cmdline.c_str(), O_RDONLY); + if (fd == -1) + THROW(ErrCode::RuntimeError) << "Failed to get process path: " << cmdline; + + errno = 0; + size = ::read(fd, buf.data(), buf.size()); + ::close(fd); + + if (size == -1) + THROW(ErrCode::RuntimeError) << "Failed to get process path: " << cmdline + << ", errno: " << errno; + + buf[size - 1] = '\0'; + } + + return canonicalize(std::string(buf.begin(), buf.begin() + size)); + } + +private: + static std::string canonicalize(std::string&& s) + { + auto predicate = [](unsigned char c){ return std::isspace(c) || c == '\0'; }; + auto base = std::find_if(s.begin(), s.end(), predicate); + s.erase(base, s.end()); + return s; } };