macOS port: build, rendering, daemon, and mining fixes
Build & setup: - Fix setup.sh and build.sh for macOS (bundle daemon, xmrig, sapling params, asmap.dat into .app) - Fix CMakeLists.txt libsodium linking for macOS - Fix incbin.h to use __DATA,__const section on macOS - Remove vendored libsodium-1.0.18 source tree (use fetch script instead) - Remove prebuilt-binaries/xmrig (replaced by xmrig-hac) - Add .DS_Store to .gitignore Rendering & UI: - Use GLSL #version 150 and OpenGL 3.2 Core Profile on macOS - Force dpiScale=1.0 on macOS to fix Retina double-scaling - Set default window/UI opacity to 100% on Mac/Linux - Add scroll fade shader guard for macOS GL compatibility - Add ImGui error recovery around render loop and mining tab Daemon & bootstrap: - Fix getDragonXDataDir() to return ~/Library/Application Support/Hush/DRAGONX/ on macOS - Fix isPortInUse() with connect() fallback (no /proc/net/tcp on macOS) - Increase daemon watchdog timeout from 3s to 15s - Add daemon status indicator (colored dot + label) in wizard bootstrap phases Mining tab: - Fix EmbeddedDaemon::getMemoryUsageMB() crash on macOS (was using Linux /proc) - Fix XmrigManager::getMemoryUsageMB() to use ps on macOS instead of /proc - Restructure RenderMiningTab with wrapper pattern for exception safety - Fix default pool URL to include port (pool.dragonx.is:3433)
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include "embedded_daemon.h"
|
||||
#include "../config/version.h"
|
||||
#include "../resources/embedded_resources.h"
|
||||
#include "../util/platform.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
@@ -55,6 +56,8 @@ std::string EmbeddedDaemon::findDaemonBinary()
|
||||
char exe_path[MAX_PATH];
|
||||
GetModuleFileNameA(NULL, exe_path, MAX_PATH);
|
||||
exe_dir = fs::path(exe_path).parent_path().string();
|
||||
#elif defined(__APPLE__)
|
||||
exe_dir = util::Platform::getExecutableDirectory();
|
||||
#else
|
||||
char exe_path[4096];
|
||||
ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
|
||||
@@ -349,25 +352,35 @@ static bool isPortInUse(int port)
|
||||
WSACleanup();
|
||||
return (result == 0);
|
||||
#else
|
||||
// Read /proc/net/tcp to check for listeners — avoids creating sockets
|
||||
// which would add conntrack entries and consume ephemeral ports.
|
||||
// On macOS /proc doesn't exist; on Linux prefer /proc/net/tcp to avoid
|
||||
// creating sockets. Fall back to connect() if /proc is unavailable.
|
||||
FILE* fp = fopen("/proc/net/tcp", "r");
|
||||
if (!fp) return false;
|
||||
char line[256];
|
||||
unsigned int localPort, state;
|
||||
bool found = false;
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
// Format: sl local_address rem_address st ...
|
||||
// local_address is HEXIP:HEXPORT, state 0x0A = TCP_LISTEN
|
||||
if (sscanf(line, " %*d: %*X:%X %*X:%*X %X", &localPort, &state) == 2) {
|
||||
if (localPort == static_cast<unsigned int>(port) && state == 0x0A) {
|
||||
found = true;
|
||||
break;
|
||||
if (fp) {
|
||||
char line[256];
|
||||
unsigned int localPort, state;
|
||||
bool found = false;
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
if (sscanf(line, " %*d: %*X:%X %*X:%*X %X", &localPort, &state) == 2) {
|
||||
if (localPort == static_cast<unsigned int>(port) && state == 0x0A) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return found;
|
||||
}
|
||||
fclose(fp);
|
||||
return found;
|
||||
// Fallback (macOS): try to connect
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) return false;
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(static_cast<uint16_t>(port));
|
||||
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
int result = connect(sock, (struct sockaddr*)&addr, sizeof(addr));
|
||||
close(sock);
|
||||
return (result == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -925,7 +938,23 @@ double EmbeddedDaemon::getMemoryUsageMB() const
|
||||
{
|
||||
if (process_pid_ <= 0) return 0.0;
|
||||
|
||||
// The tracked PID is often a bash wrapper script; the real daemon
|
||||
#ifdef __APPLE__
|
||||
// macOS: use ps to read RSS for the daemon process and its children
|
||||
// in the same process group.
|
||||
char cmd[128];
|
||||
snprintf(cmd, sizeof(cmd), "ps -o rss= -g %d 2>/dev/null", process_pid_);
|
||||
FILE* fp = popen(cmd, "r");
|
||||
if (!fp) return 0.0;
|
||||
double total_rss_mb = 0.0;
|
||||
char line[64];
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
long rss_kb = atol(line);
|
||||
if (rss_kb > 0) total_rss_mb += static_cast<double>(rss_kb) / 1024.0;
|
||||
}
|
||||
pclose(fp);
|
||||
return total_rss_mb;
|
||||
#else
|
||||
// Linux: The tracked PID is often a bash wrapper script; the real daemon
|
||||
// (dragonxd) is a child in the same process group. Sum VmRSS for every
|
||||
// process whose PGID matches our tracked PID.
|
||||
double total_rss_mb = 0.0;
|
||||
@@ -975,6 +1004,7 @@ double EmbeddedDaemon::getMemoryUsageMB() const
|
||||
}
|
||||
|
||||
return total_rss_mb;
|
||||
#endif // __APPLE__ / Linux
|
||||
}
|
||||
|
||||
bool EmbeddedDaemon::isRunning() const
|
||||
|
||||
@@ -512,6 +512,21 @@ bool XmrigManager::isRunning() const {
|
||||
|
||||
double XmrigManager::getMemoryUsageMB() const {
|
||||
if (process_pid_ <= 0) return 0.0;
|
||||
#ifdef __APPLE__
|
||||
// macOS: use ps to read RSS for xmrig process
|
||||
char cmd[128];
|
||||
snprintf(cmd, sizeof(cmd), "ps -o rss= -p %d 2>/dev/null", process_pid_);
|
||||
FILE* fp = popen(cmd, "r");
|
||||
if (!fp) return 0.0;
|
||||
char line[64];
|
||||
double mb = 0.0;
|
||||
if (fgets(line, sizeof(line), fp)) {
|
||||
long rss_kb = atol(line);
|
||||
if (rss_kb > 0) mb = static_cast<double>(rss_kb) / 1024.0;
|
||||
}
|
||||
pclose(fp);
|
||||
return mb;
|
||||
#else
|
||||
char path[64];
|
||||
snprintf(path, sizeof(path), "/proc/%d/statm", process_pid_);
|
||||
FILE* fp = fopen(path, "r");
|
||||
@@ -523,6 +538,7 @@ double XmrigManager::getMemoryUsageMB() const {
|
||||
fclose(fp);
|
||||
long pageSize = sysconf(_SC_PAGESIZE);
|
||||
return static_cast<double>(pages * pageSize) / (1024.0 * 1024.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void XmrigManager::drainOutput() {
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
|
||||
/// User-facing config (maps 1:1 to UI fields / Settings)
|
||||
struct Config {
|
||||
std::string pool_url = "pool.dragonx.is";
|
||||
std::string pool_url = "pool.dragonx.is:3433";
|
||||
std::string wallet_address;
|
||||
std::string worker_name = "x";
|
||||
std::string algo = "rx/hush";
|
||||
|
||||
Reference in New Issue
Block a user