procctrl is a simple, cross-platform, header-only C++ library to manage process suspension and resumption. It supports Windows and Linux (macOS is not supported).
- Suspend or resume a process by PID
- Suspend or resume all processes by executable name
- Check if a process exists and if it can be controlled
- Get parent PID or all descendants (process tree)
- Automatically handles sandboxed applications on Linux (e.g., Snap/Flatpak)
- Pure header-only, no compilation required
- Uses NT API functions (
NtSuspendProcess/NtResumeProcess) fromntdll.dll - Attempts to enable SeDebugPrivilege to control other users' processes
- Falls back gracefully if permissions are insufficient
- Non-sandboxed apps: sends
SIGSTOP(suspend) andSIGCONT(resume) - Sandboxed apps in cgroup v2: writes
1/0tocgroup.freezefor freezing/thawing - Traverses
/procto find processes and parent/child relationships - Supports cgroup-aware suspension to prevent partial freezes for multi-process applications
Simply include the header in your project:
#include "procctrl.hpp"No compilation or linking is required.
#include "procctrl.hpp"
#include <iostream>
int main() {
auto pid = procctrl::find_process_by_name("firefox");
if (pid != -1) {
procctrl::set_process_suspended(pid, true); // suspend
std::cout << "Process suspended!" << std::endl;
procctrl::set_process_suspended(pid, false); // resume
std::cout << "Process resumed!" << std::endl;
}
}You can also suspend or resume all processes by name:
int suspended_count = procctrl::suspend_processes_by_name("firefox");
int resumed_count = procctrl::resume_processes_by_name("firefox");-
bool enable_debug_privilege()
EnablesSeDebugPrivilegeto control processes owned by other users. -
void init_nt_functions()
Loads NT functions (NtSuspendProcess/NtResumeProcess) fromntdll.dlland enables debug privileges.
-
bool is_cgroup_v2_available()
Checks if cgroup v2 is mounted on the system. -
int get_max_pid()
Returns the maximum PID value configured on the system (default 32768 if unavailable). -
std::string get_cgroup_v2_path(pid_t pid)
Returns the cgroup v2 path for a process, or an empty string if unavailable.
-
bool process_exists(pid_t pid)
Returns true if the process exists. -
bool can_control_process(pid_t pid)
Returns true if the current user can suspend/resume the process. -
pid_t find_process_by_name(const std::string& exe_name)
Returns the PID of the first process with the given executable name, or -1 if not found. -
std::vector<pid_t> find_all_processes_by_name(const std::string& exe_name)
Returns all PIDs matching the executable name. -
pid_t get_parent_pid(pid_t pid)
Returns the parent PID of the given process, or -1 on error. -
bool set_process_suspended(pid_t pid, bool suspend)
Suspends (true) or resumes (false) a single process by PID. Handles sandboxed apps and cgroups on Linux. -
int suspend_processes_by_name(const std::string& exe_name)
Suspends all processes with the given name. On Linux, only freezes each cgroup once. Returns the number successfully suspended. -
int resume_processes_by_name(const std::string& exe_name)
Resumes all processes with the given name. On Linux, only thaws each cgroup once. Returns the number successfully resumed. -
std::vector<pid_t> get_process_tree(pid_t root_pid)
Returns a vector containing the root PID and all descendant PIDs.
MIT License. See LICENSE file.
Based on work from: