1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
/**********************************************************************
Audacity: A Digital Audio Editor
@file IPCClient.cpp
@author Vitaly Sverchinsky
Part of lib-ipc library
**********************************************************************/
#include "IPCClient.h"
#include "IPCChannel.h"
#include <cstdint>
#include <thread>
#include <stdexcept>
#include "internal/ipc-types.h"
#include "internal/socket_guard.h"
#include "internal/BufferedIPCChannel.h"
class IPCClient::Impl final
{
std::unique_ptr<BufferedIPCChannel> mChannel;
public:
Impl(int port, IPCChannelStatusCallback& callback)
{
auto fd = socket_guard { socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) };
if(!fd)
throw std::runtime_error("cannot create socket");
#if defined(__unix__) || defined(__APPLE__)
auto fdFlags = fcntl(*fd, F_GETFD, 0);
if(fdFlags != -1)
fcntl(*fd, F_SETFD, fdFlags | FD_CLOEXEC);
#endif
sockaddr_in addrin {};
addrin.sin_family = AF_INET;
addrin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addrin.sin_port = htons(static_cast<uint16_t>(port));
if(connect(*fd, reinterpret_cast<const sockaddr*>(&addrin), sizeof(addrin)) == SOCKET_ERROR)
{
callback.OnConnectionError();
return;
}
mChannel = std::make_unique<BufferedIPCChannel>();
mChannel->StartConversation(fd.release(), callback);
}
};
IPCClient::IPCClient(int port, IPCChannelStatusCallback& callback)
{
#ifdef _WIN32
WSADATA wsaData;
auto result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != NO_ERROR)
throw std::runtime_error("WSAStartup failed");
#endif
mImpl = std::make_unique<Impl>(port, callback);
}
IPCClient::~IPCClient() = default;
|