diff options
Diffstat (limited to 'compat')
| -rw-r--r-- | compat/mutex.cpp | 30 | ||||
| -rw-r--r-- | compat/mutex.hpp | 18 | ||||
| -rw-r--r-- | compat/process-list.cpp | 188 | ||||
| -rw-r--r-- | compat/process-list.hpp | 217 | ||||
| -rw-r--r-- | compat/qt-signal.hpp | 7 |
5 files changed, 214 insertions, 246 deletions
diff --git a/compat/mutex.cpp b/compat/mutex.cpp index 664677ea..71f42329 100644 --- a/compat/mutex.cpp +++ b/compat/mutex.cpp @@ -1,33 +1,31 @@ +#include "export.hpp" #include "mutex.hpp" #include <cstdlib> +#include <QMutex> +#include <QRecursiveMutex> -mutex& mutex::operator=(const mutex& rhs) +template<typename M> +mutex<M>& mutex<M>::operator=(const mutex& rhs) { - if (rhs->isRecursive() != inner.isRecursive()) - std::abort(); - return *this; } -mutex::mutex(const mutex& datum) : mutex{datum.inner.isRecursive() ? Recursive : NonRecursive} -{ -} +template<typename MutexType> MutexType* mutex<MutexType>::operator&() const { return &inner; } -mutex::mutex(RecursionMode m) : inner{m} -{ -} +template<typename M> mutex<M>::mutex(const mutex<M>& datum) {} +template<typename M> mutex<M>::mutex() = default; -QMutex* mutex::operator&() const noexcept +template<typename M> +mutex<M>::operator M*() const noexcept { return &inner; } -mutex::operator QMutex*() const noexcept +template<typename M> +M* mutex<M>::operator->() const noexcept { return &inner; } -QMutex* mutex::operator->() const noexcept -{ - return &inner; -} +template class OTR_COMPAT_EXPORT mutex<QMutex>; +template class OTR_COMPAT_EXPORT mutex<QRecursiveMutex>; diff --git a/compat/mutex.hpp b/compat/mutex.hpp index 54758a08..6ba4fa8c 100644 --- a/compat/mutex.hpp +++ b/compat/mutex.hpp @@ -1,24 +1,18 @@ #pragma once -#include <QMutex> - #include "export.hpp" +template<typename MutexType> class OTR_COMPAT_EXPORT mutex { - mutable QMutex inner; + mutable MutexType inner{}; public: - using RecursionMode = QMutex::RecursionMode; - static constexpr RecursionMode Recursive = RecursionMode::Recursive; - static constexpr RecursionMode NonRecursive = RecursionMode::NonRecursive; - mutex& operator=(const mutex& datum); + MutexType* operator&() const; mutex(const mutex& datum); - explicit mutex(RecursionMode m); - mutex() : mutex{NonRecursive} {} + explicit mutex(); - QMutex* operator&() const noexcept; - explicit operator QMutex*() const noexcept; - QMutex* operator->() const noexcept; + explicit operator MutexType*() const noexcept; + MutexType* operator->() const noexcept; }; diff --git a/compat/process-list.cpp b/compat/process-list.cpp new file mode 100644 index 00000000..690c9e69 --- /dev/null +++ b/compat/process-list.cpp @@ -0,0 +1,188 @@ +#include "process-list.hpp" + +#ifdef _WIN32 + +#include <windows.h> +#include <tlhelp32.h> + +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(QString{e.szExeFile}); + } while (Process32Next(h, &e) == TRUE); + + CloseHandle(h); + + return ret; +} + +#elif defined __APPLE__ + +QStringList get_all_executable_names() +{ + std::vector<QString> ret; ret.reserve(512); + std::vector<int> vec; vec.reserve(512); + + 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 == QStringLiteral("wine.bin") || tmp == QStringLiteral("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 <cerrno> + +#ifdef OTR_HAS_LIBPROC2 +#include <libproc2/pids.h> +QStringList get_all_executable_names() +{ + QStringList ret; + enum pids_item items[] = { PIDS_ID_PID, PIDS_CMD, PIDS_CMDLINE_V }; + + enum rel_items { rel_pid, rel_cmd, rel_cmdline }; + struct pids_info *info = NULL; + struct pids_stack *stack; + QString tmp; tmp.reserve(64); + + procps_pids_new(&info, items, 3); + + while ((stack = procps_pids_get(info, PIDS_FETCH_TASKS_ONLY))) + { + char **p_cmdline = PIDS_VAL(rel_cmdline, strv, stack, info); + + // note, wine sets argv[0] so no parsing like in OSX case + if (p_cmdline && p_cmdline[0] && p_cmdline[0][0] && + !(p_cmdline[0][0] == '-' && !p_cmdline[0][1])) + { + tmp = QString{p_cmdline[0]}; + const int idx = std::max(tmp.lastIndexOf('\\'), tmp.lastIndexOf('/')); + if (idx != -1) + tmp = tmp.mid(idx+1); + //qDebug() << "procps" << tmp; + ret.append(tmp); + } + } + //qDebug() << "-- procps end"; + + procps_pids_unref(&info); + + return ret; +} +#else +#include <proc/readproc.h> +#include <cerrno> + +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; +} +#endif + +#else +QStringList get_all_executable_names() { return {}; } + +#endif diff --git a/compat/process-list.hpp b/compat/process-list.hpp index 39e12603..361efa4f 100644 --- a/compat/process-list.hpp +++ b/compat/process-list.hpp @@ -7,218 +7,9 @@ #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 "export.hpp" #include <vector> +#include <QString> +#include <QList> -template<typename = void> -static QStringList get_all_executable_names() -{ - QStringList ret; ret.reserve(2048); - 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 == QStringLiteral("wine.bin") || tmp == QStringLiteral("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 <cerrno> - -#ifdef OTR_HAS_LIBPROC2 -#include <libproc2/pids.h> -template<typename = void> -QStringList get_all_executable_names() -{ - QStringList ret; ret.reserve(2048); - enum pids_item items[] = { PIDS_ID_PID, PIDS_CMD, PIDS_CMDLINE_V }; - - enum rel_items { rel_pid, rel_cmd, rel_cmdline }; - struct pids_info *info = NULL; - struct pids_stack *stack; - QString tmp; tmp.reserve(255); - - procps_pids_new(&info, items, 3); - - // procps-ng version 4.0.5 removed an unused argument in PIDS_VAL() macro. - // cf. https://gitlab.com/procps-ng/procps/-/commit/967fdcfb06e20aad0f3 - - // Although the emitted machine code is identical, backward API - // compatibility was silently broken in the patch with no upgrade path - // (e.g. deprecating PIDS_VAL() while introducing PIDS_VAL2()). - - // Unfortunately, procps-ng doesn't include a #define for identifying its - // version. For these reasons the code below depends on undocumented ABI - // compatibility between procps-ng versions.. -sh 20241226 - -#define OPENTRACK_PIDS_VAL(i, type, stack) stack->head[i].result.type - - while ((stack = procps_pids_get(info, PIDS_FETCH_TASKS_ONLY))) - { - char **p_cmdline = OPENTRACK_PIDS_VAL(rel_cmdline, strv, stack); - - // note, wine sets argv[0] so no parsing like in OSX case - if (p_cmdline && p_cmdline[0] && p_cmdline[0][0] && - !(p_cmdline[0][0] == '-' && !p_cmdline[0][1])) - { - tmp = QString{p_cmdline[0]}; - const int idx = std::max(tmp.lastIndexOf('\\'), tmp.lastIndexOf('/')); - if (idx != -1) - tmp = tmp.mid(idx+1); - //qDebug() << "procps" << tmp; - ret.append(tmp); - } - } - //qDebug() << "-- procps end"; - - procps_pids_unref(&info); - - return ret; -} -#else -#include <proc/readproc.h> -#include <cerrno> - -template<typename = void> -QStringList get_all_executable_names() -{ - QStringList ret; ret.reserve(2048); - 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; -} -#endif - -#else -template<typename = void> -static QStringList get_all_executable_names() -{ - return QStringList(); -} -#endif +OTR_COMPAT_EXPORT QStringList get_all_executable_names(); diff --git a/compat/qt-signal.hpp b/compat/qt-signal.hpp index f74de642..92ab7e6f 100644 --- a/compat/qt-signal.hpp +++ b/compat/qt-signal.hpp @@ -3,9 +3,10 @@ // this is to avoid dealing with QMetaObject for the time being -sh 20190203 #include "export.hpp" -namespace options { class slider_value; } #include <QObject> #include <QList> +#include <QPointF> +#include <QVariant> namespace _qt_sig_impl { @@ -52,14 +53,11 @@ template<> struct sig<void> { using t = sig_void; }; template<> struct sig<type> { using t = sig_##type; }; \ template<> struct sig<qlist##type> { using t = qlist##type; } -using slider_value = options::slider_value; - OTR_GENERATE_SIGNAL(int); OTR_GENERATE_SIGNAL(double); OTR_GENERATE_SIGNAL(float); OTR_GENERATE_SIGNAL(bool); OTR_GENERATE_SIGNAL(QString); -OTR_GENERATE_SIGNAL(slider_value); OTR_GENERATE_SIGNAL(QPointF); OTR_GENERATE_SIGNAL(QVariant); @@ -69,4 +67,3 @@ OTR_GENERATE_SIGNAL(QVariant); #undef OTR_GENERATE_SIGNAL template<typename t> using qt_signal = typename _qt_sig_impl::sig<t>::t; - |
