代码拉取完成,页面将自动刷新
#include "process_helper.h"
#include <dirent.h>
#include <signal.h>
#include <sys/prctl.h>
#include <sys/stat.h> // For chmod()
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <algorithm>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <memory>
#include <regex> // NOLINT
#include <string>
#include <cstring>
#include <utility>
#include <vector>
// RAII class to automatically close file on destruction
class FileCloser {
public:
explicit FileCloser(std::ifstream& file) : file_(file) {
}
~FileCloser() {
if (file_.is_open()) {
file_.close();
}
}
std::ifstream& get() const {
return file_;
}
private:
std::ifstream& file_;
};
/**
* @brief RAII wrapper for DIR* to ensure proper closing
*/
class DirCloser {
public:
explicit DirCloser(DIR* dir) : dir_(dir) {
}
~DirCloser() {
if (dir_) {
closedir(dir_);
}
}
DIR* get() const {
return dir_;
} // Provide a getter for the internal DIR pointer
private:
DIR* dir_;
};
/**
* @brief Function to check if the process is not in stopped state
*
* @param [in] pid - pid find by process name
* @return true - stopped; false - not stopped
*/
bool IsProcessStopped(pid_t pid) {
std::ifstream statusStream(std::string("/proc/") + std::to_string(pid) +
"/status");
std::string line;
std::regex stateRegex("^State:\\s+([^\\(]+)\\(");
while (getline(statusStream, line)) {
std::smatch match;
if (std::regex_search(line, match, stateRegex)) {
std::string state = match[1].str(); // Get the matched state string
// Remove leading and trailing spaces using regex_replace
state = std::regex_replace(state, std::regex("^\\s+|\\s+$"), "");
if (state == "T") {
std::cerr << "Process " << pid << " status is " << state
<< " is in stopped state.\n";
return true;
} else {
std::cout << "Process " << pid << " status is " << state
<< " is not in stopped state.\n";
return false;
}
}
}
return true; // Error or process not found
}
/**
* @brief Function to find the PID of a process by its name
* @param [in] process_name process name
* @param [out] pid process id
* @return true - find pid by process name; false - not find pid by process
* name
*/
bool FindPidByProcessName(const std::string& process_name, pid_t& pid) { //NOLINT
DirCloser dir(opendir("/proc"));
if (!dir.get()) {
std::cerr << "Failed to open directory /proc" << std::endl;
return false;
}
struct dirent* entry;
while ((entry = readdir(dir.get())) != nullptr) {
// Check if the entry is a directory and its name is numeric
if (entry->d_type == DT_DIR) {
std::string pid_str = entry->d_name;
if (pid_str.find_first_not_of("0123456789") == std::string::npos) {
// Read the "cmdline" file to get the process name
std::string cmdline_path = "/proc/" + pid_str + "/cmdline";
std::ifstream cmdline_file(cmdline_path);
// FileCloser to manage cmdline_file
FileCloser file_closer(cmdline_file);
if (cmdline_file.is_open()) {
std::stringstream cmdline_stream;
cmdline_stream << cmdline_file.rdbuf();
std::string cmdLine = cmdline_stream.str();
// Check if the process name matches
if (cmdLine.find(process_name) != std::string::npos) {
pid = std::stoi(pid_str);
// just return the first pid found
return true;
}
} else {
std::cerr << "Failed to open " << cmdline_path << std::endl;
}
}
}
}
return false;
}
/**
* @brief Function to try to resume a stopped process
*
* @param [in] attempts - if resume failed, try another attempts times.
* @param [in] pid - pid find by process name.
* @return true - Resume successfully; false - Resume failed
*/
bool TryToResumeProcessByPid(pid_t pid, int attempts) {
for (int i = 0; i < attempts; ++i) {
if (kill(pid, SIGCONT) == 0) {
usleep(1000); // sleep 1ms, wait for process status
if (!IsProcessStopped(pid)) {
std::cout << "Process " << pid << " resumed successfully.\n";
return true;
}
usleep(1000 * 100); // sleep 100ms, wait for another try
}
}
std::cout << "Failed to resume process " << pid << " after " << attempts
<< " attempts.\n";
return false;
}
/**
* @brief Function to check if the process is not in stopped state
*
* @param [in] pid - pid find by process name.
* @return true - Freeze successfully; false - Freeze failed
*/
bool FreezeProcessByPid(pid_t pid) {
if (kill(pid, SIGSTOP) == -1) {
std::cerr << "Failed to send SIGSTOP to process, pid" << pid << std::endl;
return false;
} else {
std::cout << "Success to send SIGSTOP to process " << pid << std::endl;
}
usleep(1000); // sleep 1ms, wait for process status
if (IsProcessStopped(pid)) {
std::cerr << "Process " << pid << " freeze success." << std::endl;
return true;
}
return false;
}
/**
* @brief Function to check if the process is not in stopped state
*
* @param [in] process_name - process name.
* @return 0 - Freeze successfully;-1 - cannot found process;-2 - Freeze failed
*/
int FreezeProcessByName(const std::string& process_name) {
pid_t pid;
if (!FindPidByProcessName(process_name, pid)) {
std::cerr << "Cannot find procass, " << process_name << std::endl;
return -1;
}
if (!FreezeProcessByPid(pid)) {
std::cerr << "process_name " << process_name << " pid " << pid
<< " freeze failed.\n";
return -2;
} else {
std::cout << "process_name " << process_name << " pid " << pid
<< " freeze success.\n";
return 0;
}
}
/**
* @brief Function to try to resume a stopped process
*
* @param [in] process_name - process name.
* @param [in] attempts - if resume failed, try another attempts times.
* @return 0 - successfully; -1 - not found process; -2 resume failed
*/
int TryToResumeProcessByName(const std::string& process_name, int attempts) {
pid_t pid;
if (!FindPidByProcessName(process_name, pid)) {
std::cerr << "Cannot find process " << process_name << std::endl;
return -1;
}
bool ret = TryToResumeProcessByPid(pid, attempts);
if (!ret) {
return -2;
} else {
return 0;
}
}
/**
* @brief terminate a process
*
* @param [in] process_name - process name.
* @param [in] attempts - if resume failed, try another attempts times.
* @return 0 - successfully; -1 - not found process; -2 terminate failed
* -3 - Handle waitpid error
*/
int TerminateProcess(const std::string& process_name, int attempts) {
pid_t pid;
if (!FindPidByProcessName(process_name, pid)) {
std::cerr << "Cannot find process " << process_name << std::endl;
return -1;
}
for (int i = 0; i < attempts; ++i) {
if (kill(pid, SIGKILL) == 0) {
std::cout << "Process with PID: " << pid << " has been terminated.\n";
int status;
if (waitpid(pid, &status, 0) == -1) {
std::cerr << "Error waiting for process " << pid << ": "
<< strerror(errno) << std::endl;
return -3; // Handle waitpid error
}
return 0;
} else {
std::cerr << "Failed to kill process with PID: " << pid << std::endl;
}
}
std::cerr << "Failed to kill process with PID: " << pid << " after "
<< attempts << " attempts.\n";
return -2; // Handle kill attempts failure
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。