Skip to content

global rule for spawnWithRule #9479

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 92 additions & 1 deletion src/helpers/MiscFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ void logSystemInfo() {
Debug::log(NONE, "{}", NFsUtils::readFileAsString("/etc/os-release").value_or("error"));
}

int64_t getPPIDof(int64_t pid) {
pid_t getPPIDof(pid_t pid) {
#if defined(KERN_PROC_PID)
int mib[] = {
CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)pid,
Expand Down Expand Up @@ -606,6 +606,97 @@ int64_t getPPIDof(int64_t pid) {
#endif
}

std::vector<pid_t> getAllPIDOf(const std::string& name) {
std::vector<pid_t> results;

#if defined(KERN_PROC_ALL)
int mib[] = {CTL_KERN,
KERN_PROC,
KERN_PROC_ALL,
#if defined(__NetBSD__) || defined(__OpenBSD__)
0,
sizeof(KINFO_PROC),
0
#endif
};
u_int miblen = sizeof(mib) / sizeof(mib[0]);

size_t size = 0;
if (sysctl(mib, miblen, NULL, &size, NULL, 0) == -1)
return results;

std::vector<KINFO_PROC> kprocList(size / sizeof(KINFO_PROC));

if (sysctl(mib, miblen, kprocList.data(), &size, NULL, 0) != -1) {
for (auto& kproc : kprocList) {
#if defined(__DragonFly__)
if (name == std::string(kproc.kp_comm))
results.push_back(kproc.kp_pid);
#elif defined(__FreeBSD__)
if (name == std::string(kproc.ki_comm))
results.push_back(kproc.ki_pid);
#else
if (name == std::string(kproc.p_comm))
results.push_back(kproc.p_pid);
#endif
}
}
#else
std::error_code ec;
for (const auto& entry : std::filesystem::directory_iterator("/proc", ec)) {
if (!entry.is_directory())
continue;

const auto& dirname = entry.path().filename().string();
if (!isNumber(dirname))
continue;

const auto pid = std::stoll(dirname);
std::string procName = binaryNameForPid(pid).value_or("");

if (procName == name)
results.push_back(pid);
}
#endif

return results;
}

std::expected<std::string, std::string> binaryNameForPid(pid_t pid) {
if (pid <= 0)
return std::unexpected("No pid for client");

#if defined(KERN_PROC_PATHNAME)
int mib[] = {
CTL_KERN,
#if defined(__NetBSD__)
KERN_PROC_ARGS,
pid,
KERN_PROC_PATHNAME,
#else
KERN_PROC,
KERN_PROC_PATHNAME,
pid,
#endif
};
u_int miblen = sizeof(mib) / sizeof(mib[0]);
char exe[PATH_MAX] = "/nonexistent";
size_t sz = sizeof(exe);
sysctl(mib, miblen, &exe, &sz, NULL, 0);
std::string path = exe;
#else
std::string path = std::format("/proc/{}/exe", (uint64_t)pid);
#endif
std::error_code ec;

std::string fullPath = std::filesystem::canonical(path, ec);

if (ec)
return std::unexpected("canonical failed");

return fullPath;
}

std::expected<int64_t, std::string> configStringToInt(const std::string& VALUE) {
auto parseHex = [](const std::string& value) -> std::expected<int64_t, std::string> {
try {
Expand Down
44 changes: 23 additions & 21 deletions src/helpers/MiscFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,29 @@ struct SWorkspaceIDName {
std::string name;
};

std::string absolutePath(const std::string&, const std::string&);
std::string escapeJSONStrings(const std::string& str);
bool isDirection(const std::string&);
bool isDirection(const char&);
SWorkspaceIDName getWorkspaceIDNameFromString(const std::string&);
std::optional<std::string> cleanCmdForWorkspace(const std::string&, std::string);
float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2);
void logSystemInfo();
std::string execAndGet(const char*);
int64_t getPPIDof(int64_t pid);
std::expected<int64_t, std::string> configStringToInt(const std::string&);
Vector2D configStringToVector2D(const std::string&);
std::optional<float> getPlusMinusKeywordResult(std::string in, float relative);
double normalizeAngleRad(double ang);
std::vector<SCallstackFrameInfo> getBacktrace();
void throwError(const std::string& err);
bool envEnabled(const std::string& env);
Hyprutils::OS::CFileDescriptor allocateSHMFile(size_t len);
bool allocateSHMFilePair(size_t size, Hyprutils::OS::CFileDescriptor& rw_fd_ptr, Hyprutils::OS::CFileDescriptor& ro_fd_ptr);
float stringToPercentage(const std::string& VALUE, const float REL);
bool isNvidiaDriverVersionAtLeast(int threshold);
std::string absolutePath(const std::string&, const std::string&);
std::string escapeJSONStrings(const std::string& str);
bool isDirection(const std::string&);
bool isDirection(const char&);
SWorkspaceIDName getWorkspaceIDNameFromString(const std::string&);
std::optional<std::string> cleanCmdForWorkspace(const std::string&, std::string);
float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2);
void logSystemInfo();
std::string execAndGet(const char*);
pid_t getPPIDof(pid_t pid);
std::expected<std::string, std::string> binaryNameForPid(pid_t pid);
std::vector<pid_t> getAllPIDOf(const std::string& name);
std::expected<int64_t, std::string> configStringToInt(const std::string&);
Vector2D configStringToVector2D(const std::string&);
std::optional<float> getPlusMinusKeywordResult(std::string in, float relative);
double normalizeAngleRad(double ang);
std::vector<SCallstackFrameInfo> getBacktrace();
void throwError(const std::string& err);
bool envEnabled(const std::string& env);
Hyprutils::OS::CFileDescriptor allocateSHMFile(size_t len);
bool allocateSHMFilePair(size_t size, Hyprutils::OS::CFileDescriptor& rw_fd_ptr, Hyprutils::OS::CFileDescriptor& ro_fd_ptr);
float stringToPercentage(const std::string& VALUE, const float REL);
bool isNvidiaDriverVersionAtLeast(int threshold);

template <typename... Args>
[[deprecated("use std::format instead")]] std::string getFormat(std::format_string<Args...> fmt, Args&&... args) {
Expand Down
25 changes: 19 additions & 6 deletions src/managers/KeybindManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "../render/Renderer.hpp"
#include "../hyprerror/HyprError.hpp"
#include "../config/ConfigManager.hpp"
#include "../helpers/MiscFunctions.hpp"

#include <optional>
#include <iterator>
Expand Down Expand Up @@ -921,11 +922,11 @@ bool CKeybindManager::handleInternalKeybinds(xkb_keysym_t keysym) {

// Dispatchers
SDispatchResult CKeybindManager::spawn(std::string args) {
const uint64_t PROC = spawnWithRules(args, nullptr);
const pid_t PROC = spawnWithRules(args, nullptr);
return {.success = PROC > 0, .error = std::format("Failed to start process {}", args)};
}

uint64_t CKeybindManager::spawnWithRules(std::string args, PHLWORKSPACE pInitialWorkspace) {
pid_t CKeybindManager::spawnWithRules(std::string args, PHLWORKSPACE pInitialWorkspace) {

args = trim(args);

Expand All @@ -937,13 +938,25 @@ uint64_t CKeybindManager::spawnWithRules(std::string args, PHLWORKSPACE pInitial
args = args.substr(args.find_first_of(']') + 1);
}

const uint64_t PROC = spawnRawProc(args, pInitialWorkspace);
const pid_t PROC = spawnRawProc(args, pInitialWorkspace);

if (!RULES.empty()) {
const auto RULESLIST = CVarList(RULES, 0, ';');
auto global = false;

for (auto const& r : RULESLIST) {
g_pConfigManager->addExecRule({r, (unsigned long)PROC});
Debug::log(CRIT, "PROC = {}", PROC);
Debug::log(CRIT, "getProcNameOf(PROC) = {}", *binaryNameForPid(PROC));
Debug::log(CRIT, "getAllPIDOf(getProcNameOf(PROC)) = {}", getAllPIDOf(*binaryNameForPid(PROC)));
if (r == "global")
global = true;
else {
if (global)
for (const auto& pid : getAllPIDOf(*binaryNameForPid(PROC)))
g_pConfigManager->addExecRule({r, (unsigned long)pid});
else
g_pConfigManager->addExecRule({r, (unsigned long)PROC});
}
}

Debug::log(LOG, "Applied {} rule arguments for exec.", RULESLIST.size());
Expand All @@ -953,11 +966,11 @@ uint64_t CKeybindManager::spawnWithRules(std::string args, PHLWORKSPACE pInitial
}

SDispatchResult CKeybindManager::spawnRaw(std::string args) {
const uint64_t PROC = spawnRawProc(args, nullptr);
const pid_t PROC = spawnRawProc(args, nullptr);
return {.success = PROC > 0, .error = std::format("Failed to start process {}", args)};
}

uint64_t CKeybindManager::spawnRawProc(std::string args, PHLWORKSPACE pInitialWorkspace) {
pid_t CKeybindManager::spawnRawProc(std::string args, PHLWORKSPACE pInitialWorkspace) {
Debug::log(LOG, "Executing {}", args);

const auto HLENV = getHyprlandLaunchEnv(pInitialWorkspace);
Expand Down
4 changes: 2 additions & 2 deletions src/managers/KeybindManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ class CKeybindManager {
static void moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string& dir = "");
static void moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowInDirection);
static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool preserveFocusHistory = false);
static uint64_t spawnRawProc(std::string, PHLWORKSPACE pInitialWorkspace);
static uint64_t spawnWithRules(std::string, PHLWORKSPACE pInitialWorkspace);
static pid_t spawnRawProc(std::string, PHLWORKSPACE pInitialWorkspace);
static pid_t spawnWithRules(std::string, PHLWORKSPACE pInitialWorkspace);

// -------------- Dispatchers -------------- //
static SDispatchResult closeActive(std::string);
Expand Down
36 changes: 1 addition & 35 deletions src/managers/permissions/DynamicPermissionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <filesystem>
#include "../../Compositor.hpp"
#include "../../config/ConfigValue.hpp"
#include "../../helpers/MiscFunctions.hpp"

#include <hyprutils/string/String.hpp>
using namespace Hyprutils::String;
Expand Down Expand Up @@ -69,41 +70,6 @@ static const char* permissionToHumanString(eDynamicPermissionType type) {
return "error";
}

static std::expected<std::string, std::string> binaryNameForPid(pid_t pid) {
if (pid <= 0)
return std::unexpected("No pid for client");

#if defined(KERN_PROC_PATHNAME)
int mib[] = {
CTL_KERN,
#if defined(__NetBSD__)
KERN_PROC_ARGS,
pid,
KERN_PROC_PATHNAME,
#else
KERN_PROC,
KERN_PROC_PATHNAME,
pid,
#endif
};
u_int miblen = sizeof(mib) / sizeof(mib[0]);
char exe[PATH_MAX] = "/nonexistent";
size_t sz = sizeof(exe);
sysctl(mib, miblen, &exe, &sz, NULL, 0);
std::string path = exe;
#else
std::string path = std::format("/proc/{}/exe", (uint64_t)pid);
#endif
std::error_code ec;

std::string fullPath = std::filesystem::canonical(path, ec);

if (ec)
return std::unexpected("canonical failed");

return fullPath;
}

static std::expected<std::string, std::string> binaryNameForWlClient(wl_client* client) {
pid_t pid = 0;
wl_client_get_credentials(client, &pid, nullptr, nullptr);
Expand Down
Loading