connection between 2 systems and bug fixes (#14)

This commit is contained in:
tompzf
2026-07-03 14:53:48 +02:00
committed by GitHub
parent 0fb5660d27
commit 46842200f1
284 changed files with 35200 additions and 8265 deletions

View File

@@ -81,19 +81,19 @@ namespace
// Directory selection (/run/user/<uid>/sdv or /tmp/sdv)
std::string CUnixDomainSocketsChannelMgnt::MakeUserRuntimeDir()
{
std::ostringstream oss;
oss << "/run/user/" << ::getuid();
const std::string path = "/run/ipc/sdv";
struct stat st{};
if (::stat(oss.str().c_str(), &st) == 0)
if (::stat(path.c_str(), &st) == 0)
{
std::string path = oss.str() + "/sdv";
::mkdir(path.c_str(), 0770);
return path;
}
::mkdir("/tmp/sdv", 0770);
return "/tmp/sdv";
// fallback if /run/ipc/sdv is not available
const std::string fallback = "/tmp/sdv";
::mkdir(fallback.c_str(), 0770);
return fallback;
}
bool CUnixDomainSocketsChannelMgnt::OnInitialize()
@@ -102,7 +102,11 @@ bool CUnixDomainSocketsChannelMgnt::OnInitialize()
}
void CUnixDomainSocketsChannelMgnt::OnShutdown()
{}
void CUnixDomainSocketsChannelMgnt::OnDestroy()
{
m_watchdog.Clear();
}
// Endpoint creation (server)
@@ -129,33 +133,133 @@ sdv::ipc::SChannelEndpoint CUnixDomainSocketsChannelMgnt::CreateEndpoint(const s
path = ClampSunPath(path);
// Use a shared_ptr and store it to keep the server connection alive
auto server = std::make_shared<CUnixSocketConnection>(-1, true, path);
m_ServerConnections.push_back(server);
// Keep lifetime consistent with shared_mem: watchdog owns active connections.
std::shared_ptr<CUnixSocketConnection> server = std::make_shared<CUnixSocketConnection>(-1, true, path);
// Ignore cppcheck warning; if construction failed, an exception is expected first.
// cppcheck-suppress knownConditionTrueFalse
if (!server)
return {};
server->SetWatchDogRemoveCallback([this](const void* connection)
{
m_watchdog.RemoveConnection(connection);
});
m_watchdog.AddConnection(server);
sdv::ipc::SChannelEndpoint ep{};
ep.pConnection = static_cast<IInterfaceAccess*>(server.get());
ep.ssConnectString = server->GetConnectionString();
// Publish a Provider-wrapped connect string for compatibility with
// CCommunicationControl::CreateClientConnection() flows.
const std::string udsConnectString = server->GetConnectionString();
ep.ssConnectString = std::string("[Provider]\n") +
"Name = \"unix_domain_sockets\"\n" +
"ConnectString = \"" + udsConnectString + "\"\n";
return ep;
}
// Access existing endpoint (server or client)
sdv::IInterfaceAccess* CUnixDomainSocketsChannelMgnt::Access(const sdv::u8string& ssConnectString)
{
const auto kv = ParseKV(static_cast<std::string>(ssConnectString));
const bool isServer = (kv.count("role") && kv.at("role") == "server");
const std::string path = kv.count("path") ? kv.at("path") : (MakeUserRuntimeDir() + "/UDS_auto.sock");
const std::string input = static_cast<std::string>(ssConnectString);
if (isServer)
bool isServer = false;
bool parsed = false;
std::string path;
// Parse structured TOML forms first, but only for non-raw inputs.
// Raw connect strings (proto=uds;...) are intentionally not TOML and
// would produce noisy parser diagnostics like "Missing value".
if (input.rfind("proto=uds", 0) != 0)
{
auto server = std::make_shared<CUnixSocketConnection>(-1, true, path);
m_ServerConnections.push_back(server);
return static_cast<IInterfaceAccess*>(server.get());
sdv::toml::CTOMLParser parser(input);
if (!parser.IsValid())
return nullptr;
const std::string providerName = parser.GetDirect("Provider.Name").GetValue();
if (!providerName.empty())
{
if (providerName != "unix_domain_sockets" &&
providerName != "UnixSocketsChannelControl" &&
providerName != "UnixDomainSocketsChannelControl")
{
return nullptr;
}
const std::string nested = parser.GetDirect("Provider.ConnectString").GetValue();
if (!nested.empty())
{
const auto kv = ParseKV(nested);
if (kv.count("path"))
path = kv.at("path");
}
// Provider descriptions are consumed as client endpoints.
parsed = true;
isServer = false;
}
else
{
// Shared-memory style callers pass [IpcChannel] config directly to Access().
parsed = true;
isServer = false;
}
if (path.empty())
{
auto pathNode = parser.GetDirect("IpcChannel.Path");
if (pathNode.GetType() == sdv::toml::ENodeType::node_string)
{
path = static_cast<std::string>(pathNode.GetValue());
}
else
{
auto nameNode = parser.GetDirect("IpcChannel.Name");
if (nameNode.GetType() == sdv::toml::ENodeType::node_string)
{
const std::string name = static_cast<std::string>(nameNode.GetValue());
if (!name.empty())
path = MakeUserRuntimeDir() + "/" + name + ".sock";
}
}
}
}
// Client: allocated raw pointer (expected to be managed by SDV framework)
auto* client = new CUnixSocketConnection(-1, false, path);
return static_cast<IInterfaceAccess*>(client);
// Raw KV fallback (legacy/tests): proto=uds;role=...;path=...;
if (!parsed)
{
// Only treat as raw format when it actually starts with proto=uds.
if (input.rfind("proto=uds", 0) != 0)
return nullptr;
const auto kv = ParseKV(input);
parsed = true;
isServer = (kv.count("role") && kv.at("role") == "server");
if (kv.count("path"))
path = kv.at("path");
}
if (!parsed)
return nullptr;
if (path.empty())
path = MakeUserRuntimeDir() + "/UDS_auto.sock";
path = ClampSunPath(path);
std::shared_ptr<CUnixSocketConnection> connection =
std::make_shared<CUnixSocketConnection>(-1, isServer, path);
// Ignore cppcheck warning; if construction failed, an exception is expected first.
// cppcheck-suppress knownConditionTrueFalse
if (!connection)
return nullptr;
connection->SetWatchDogRemoveCallback([this](const void* instance)
{
m_watchdog.RemoveConnection(instance);
});
m_watchdog.AddConnection(connection);
return static_cast<IInterfaceAccess*>(connection.get());
}
#endif // defined(__unix__)