Experimental support for using the client on macOS (Darwin) (#1321)
Some checks failed
Build on RHEL9 / build (push) Failing after 32s
Build on RHEL8 / build (push) Failing after 4m40s

* shorter SHM names on macOS
* fix segfault on macOS when string is empty
* apple version of read exe path
* ifdef for linux specific API
* fixed test for shm and udp socket
* updated release notes
This commit is contained in:
Erik Fröjdh
2025-10-22 15:19:36 +02:00
committed by GitHub
parent 9d40220274
commit 1d66f1d26d
10 changed files with 88 additions and 26 deletions

View File

@@ -10,11 +10,16 @@
#include <ios>
#include <iostream>
#include <libgen.h> // dirname
#include <limits.h>
#include <sstream>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h> //readlink
#if defined(__APPLE__)
#include <mach-o/dyld.h>
#endif
namespace sls {
int readDataFile(std::ifstream &infile, short int *data, int nch, int offset) {
@@ -246,21 +251,40 @@ std::vector<int> getChannelsFromFile(const std::string &fname) {
}
std::string getAbsolutePathFromCurrentProcess(const std::string &fname) {
if (fname[0] == '/') {
return fname;
}
// get path of current binary
char path[MAX_STR_LENGTH];
memset(path, 0, MAX_STR_LENGTH);
ssize_t len = readlink("/proc/self/exe", path, MAX_STR_LENGTH - 1);
//in case PATH_MAX defines the longest possible path on linux and macOS
//use string instead of char array to avoid overflow
std::string path(PATH_MAX, '\0');
#if defined(__APPLE__)
uint32_t size = PATH_MAX;
if (_NSGetExecutablePath(path.data(), &size) != 0) {
throw std::runtime_error("Failed to get executable path");
}
// Resolve any symlinks and .. components
std::string resolved(PATH_MAX, '\0');
if (!realpath(path.data(), resolved.data())) {
throw std::runtime_error("realpath failed for executable");
}
path = resolved;
#else
ssize_t len = readlink("/proc/self/exe", path.data(), PATH_MAX - 1);
if (len < 0) {
throw RuntimeError("Could not get absolute path for " + fname);
}
path[len] = '\0';
#endif
// get dir path and attach file name
std::string absPath = (std::string(dirname(path)) + '/' + fname);
std::string absPath = (std::string(dirname(path.data())) + '/' + fname);
return absPath;
}

View File

@@ -16,7 +16,6 @@
#include <netdb.h>
#include <sstream>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
@@ -178,6 +177,12 @@ IpAddr InterfaceNameToIp(const std::string &ifn) {
}
MacAddr InterfaceNameToMac(const std::string &inf) {
#ifdef __APPLE__
throw RuntimeError(
"InterfaceNameToMac not implemented on macOS yet");
#else
// TODO! Copied from genericSocket needs to be refactored!
struct ifreq ifr;
char mac[32];
@@ -203,6 +208,7 @@ MacAddr InterfaceNameToMac(const std::string &inf) {
close(sock);
}
return MacAddr(mac);
#endif
}
void validatePortNumber(uint16_t port) {

View File

@@ -72,6 +72,10 @@ TEST_CASE("Receive data from a vector") {
CHECK(data_to_send == data_received);
}
// TODO! Test blocking on apple, investigate when implementing
// receiver support in macOS
#ifndef __APPLE__
TEST_CASE("Shutdown socket without hanging when waiting for data") {
constexpr int port = 50001;
constexpr ssize_t packet_size = 8000;
@@ -81,13 +85,14 @@ TEST_CASE("Shutdown socket without hanging when waiting for data") {
// Start a thread and wait for package
// if the socket is left open we would block
std::future<bool> ret =
std::async(&UdpRxSocket::ReceivePacket, &s, (char *)&buff);
std::async(std::launch::async, &UdpRxSocket::ReceivePacket, &s, (char *)&buff);
s.Shutdown();
auto r = ret.get();
CHECK(r == false); // since we didn't get the packet
}
#endif
TEST_CASE("Too small packet") {
constexpr int port = 50001;