OSX/linux version initial attempt

This commit is contained in:
Chris Marsh 2017-07-27 15:09:05 -07:00
parent bfcfd10baa
commit 20ad7e4ced
2 changed files with 66 additions and 27 deletions

View file

@ -15,6 +15,8 @@ endif(WIN32)
if(UNIX) if(UNIX)
add_library(discord-rpc STATIC ${BASE_RPC_SRC} connection_unix.cpp) add_library(discord-rpc STATIC ${BASE_RPC_SRC} connection_unix.cpp)
target_link_libraries(discord-rpc PUBLIC pthread)
target_compile_options(discord-rpc PRIVATE -g -Wall)
endif(UNIX) endif(UNIX)
target_include_directories(discord-rpc PRIVATE ${RAPIDJSON}/include) target_include_directories(discord-rpc PRIVATE ${RAPIDJSON}/include)

View file

@ -1,6 +1,11 @@
#include "connection.h" #include "connection.h"
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/un.h>
#include <unistd.h> #include <unistd.h>
int GetProcessId() int GetProcessId()
@ -8,52 +13,84 @@ int GetProcessId()
return ::getpid(); return ::getpid();
} }
const int RpcVersion = 1; struct BaseConnectionUnix : public BaseConnection {
const int NumFrames = 4; int sock{-1};
struct RpcConnectionUnix : public RpcConnection {
int pipe{-1};
RpcMessageFrame frames[NumFrames];
int nextFrame{0};
}; };
/*static*/ RpcConnection* RpcConnection::Create(const char* applicationId) static BaseConnectionUnix Connection;
sockaddr_un PipeAddr{};
static const char* GetTempPath()
{ {
return new RpcConnectionUnix; const char* temp = getenv("XDG_RUNTIME_DIR");
temp = temp ? temp : getenv("TMPDIR");
temp = temp ? temp : getenv("TMP");
temp = temp ? temp : getenv("TEMP");
temp = temp ? temp : "/tmp";
return temp;
} }
/*static*/ void RpcConnection::Destroy(RpcConnection*& c) /*static*/ BaseConnection* BaseConnection::Create()
{ {
auto self = reinterpret_cast<RpcConnectionUnix*&>(c); snprintf(PipeAddr.sun_path, sizeof(PipeAddr.sun_path), "%s/discord-ipc-0", GetTempPath());
delete self; PipeAddr.sun_family = AF_UNIX;
return &Connection;
}
/*static*/ void BaseConnection::Destroy(BaseConnection*& c)
{
auto self = reinterpret_cast<BaseConnectionUnix*>(c);
self->Close();
c = nullptr; c = nullptr;
} }
void RpcConnection::Open() bool BaseConnection::Open()
{ {
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
self->sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (self->sock == -1) {
return false;
}
fcntl(self->sock, F_SETFL, O_NONBLOCK);
int err = connect(self->sock, (const sockaddr*)&PipeAddr, sizeof(PipeAddr));
if (err != 0) {
self->Close();
return false;
}
return true;
} }
void RpcConnection::Close() bool BaseConnection::Close()
{ {
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
if (self->sock == -1) {
return false;
}
close(self->sock);
self->sock = -1;
return true;
} }
void RpcConnection::Write(const void* data, size_t length) bool BaseConnection::Write(const void* data, size_t length)
{ {
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
if (self->sock == -1) {
return false;
} }
RpcMessageFrame* RpcConnection::Read() ssize_t sentBytes = send(self->sock, data, length, 0);
{ return sentBytes == (ssize_t)length;
return nullptr;
} }
RpcMessageFrame* RpcConnection::GetNextFrame() bool BaseConnection::Read(void* data, size_t length)
{ {
auto self = reinterpret_cast<RpcConnectionUnix*>(this); auto self = reinterpret_cast<BaseConnectionUnix*>(this);
auto result = &(self->frames[self->nextFrame]);
self->nextFrame = (self->nextFrame + 1) % NumFrames; if (self->sock == -1) {
return result; return false;
} }
void RpcConnection::WriteFrame(RpcMessageFrame* frame) int res = recv(self->sock, data, length, 0);
{ return res == (int)length;
} }