diff options
Diffstat (limited to 'compat/process-list.hpp')
-rw-r--r-- | compat/process-list.hpp | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/compat/process-list.hpp b/compat/process-list.hpp new file mode 100644 index 00000000..10613791 --- /dev/null +++ b/compat/process-list.hpp @@ -0,0 +1,169 @@ +/* Copyright (c) 2015 Stanislaw Halik <sthalik@misaki.pl> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#pragma once + +#include <QDebug> +#include <QStringList> + +#if defined _WIN32 + +#include <windows.h> +#include <tlhelp32.h> + +template<typename = void> +static QStringList get_all_executable_names() +{ + QStringList ret; + HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (h == INVALID_HANDLE_VALUE) + return ret; + + PROCESSENTRY32 e; + e.dwSize = sizeof(e); + + if (Process32First(h, &e) != TRUE) + { + CloseHandle(h); + return ret; + } + + do { + ret.append(e.szExeFile); + } while (Process32Next(h, &e) == TRUE); + + CloseHandle(h); + + return ret; +} +#elif defined __APPLE__ +#include <libproc.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/sysctl.h> +#include <cerrno> +#include <cstring> +#include <vector> + +template<typename = void> +static QStringList get_all_executable_names() +{ + QStringList ret; + std::vector<int> vec; + + while (true) + { + int numproc = proc_listpids(PROC_ALL_PIDS, 0, nullptr, 0); + if (numproc == -1) + { + qDebug() << "proc_listpids numproc failed" << errno; + return ret; + } + vec.resize(numproc); + int cnt = proc_listpids(PROC_ALL_PIDS, 0, &vec[0], sizeof(int) * numproc); + + if (cnt <= numproc) + { + std::vector<char> arglist; + int mib[2] { CTL_KERN, KERN_ARGMAX }; + size_t sz = sizeof(int); + int maxarg = 0; + if (sysctl(mib, 2, &maxarg, &sz, NULL, 0) == -1) + { + qDebug() << "sysctl KERN_ARGMAX" << errno; + return ret; + } + arglist.resize(maxarg); + for (int i = 0; i < numproc; i++) + { + size_t maxarg_ = (size_t)maxarg; + int mib[3] { CTL_KERN, KERN_PROCARGS2, vec[i] }; + if (sysctl(mib, 3, &arglist[0], &maxarg_, NULL, 0) == -1) + { + //qDebug() << "sysctl KERN_PROCARGS2" << vec[i] << errno; + continue; + } + QStringList cmdline; + for (unsigned j = sizeof(int) + strlen(&arglist[sizeof(int)]); j < maxarg_; j++) + { + QString arg(&arglist[j]); + if (arg.size() != 0) + { + cmdline << arg; + j += arg.size(); + } + } + if (cmdline.size() > 0) + { + int idx = cmdline[0].lastIndexOf('/'); + if (idx != -1) + { + QString tmp = cmdline[0].mid(idx+1); + if (cmdline.size() > 1 && (tmp == "wine.bin" || tmp == "wine")) + { + idx = cmdline[1].lastIndexOf('/'); + if (idx == -1) + idx = cmdline[1].lastIndexOf('\\'); + if (idx != -1) + { + ret.append(cmdline[1].mid(idx+1)); + } + else + ret.append(cmdline[1]); + } + else + { + ret.append(tmp); + } + } + else + ret.append(cmdline[0]); + } + } + return ret; + } + } +} + +#elif defined __linux + +#include <proc/readproc.h> +#include <cerrno> +template<typename = void> +static QStringList get_all_executable_names() +{ + QStringList ret; + proc_t** procs = readproctab(PROC_FILLCOM); + if (procs == nullptr) + { + qDebug() << "readproctab" << errno; + return ret; + } + for (int i = 0; procs[i]; i++) + { + // note, wine sets argv[0] so no parsing like in OSX case + auto proc = procs[i]; + if (proc->cmdline && proc->cmdline[0]) + { + QString tmp(proc->cmdline[0]); + const int idx = std::max(tmp.lastIndexOf('\\'), tmp.lastIndexOf('/')); + tmp = tmp.mid(idx == -1 ? 0 : idx+1); + ret.append(tmp); + } + freeproc(procs[i]); + } + free(procs); + return ret; +} + +#else +template<typename = void> +static QStringList get_all_executable_names() +{ + return QStringList(); +} +#endif |