summaryrefslogtreecommitdiffhomepage
path: root/compat/process-list.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'compat/process-list.hpp')
-rw-r--r--compat/process-list.hpp169
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