discord-rpc/src/connection_unix.cpp

101 lines
2.2 KiB
C++
Raw Normal View History

2017-07-13 18:08:14 +01:00
#include "connection.h"
2017-07-27 23:09:05 +01:00
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
2017-07-20 22:58:23 +01:00
#include <sys/types.h>
2017-07-27 23:09:05 +01:00
#include <sys/un.h>
2017-07-20 22:58:23 +01:00
#include <unistd.h>
int GetProcessId()
{
return ::getpid();
}
2017-07-27 23:09:05 +01:00
struct BaseConnectionUnix : public BaseConnection {
int sock{-1};
2017-07-13 18:40:13 +01:00
};
2017-07-27 23:09:05 +01:00
static BaseConnectionUnix Connection;
sockaddr_un PipeAddr{};
2017-07-13 18:08:14 +01:00
2017-07-27 23:09:05 +01:00
static const char* GetTempPath()
2017-07-13 18:08:14 +01:00
{
2017-07-27 23:09:05 +01:00
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;
2017-07-13 18:08:14 +01:00
}
2017-07-27 23:09:05 +01:00
/*static*/ BaseConnection* BaseConnection::Create()
2017-07-13 18:08:14 +01:00
{
2017-07-28 00:02:47 +01:00
2017-07-27 23:09:05 +01:00
PipeAddr.sun_family = AF_UNIX;
return &Connection;
2017-07-13 18:08:14 +01:00
}
2017-07-27 23:09:05 +01:00
/*static*/ void BaseConnection::Destroy(BaseConnection*& c)
2017-07-13 18:08:14 +01:00
{
2017-07-27 23:09:05 +01:00
auto self = reinterpret_cast<BaseConnectionUnix*>(c);
self->Close();
c = nullptr;
2017-07-13 18:08:14 +01:00
}
2017-07-27 23:09:05 +01:00
bool BaseConnection::Open()
2017-07-13 18:08:14 +01:00
{
2017-07-28 00:02:47 +01:00
const char* tempPath = GetTempPath();
2017-07-27 23:09:05 +01:00
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);
2017-07-28 00:02:47 +01:00
for (int pipeNum = 0; pipeNum < 10; ++pipeNum) {
snprintf(PipeAddr.sun_path, sizeof(PipeAddr.sun_path), "%s/discord-ipc-%d", tempPath, pipeNum);
int err = connect(self->sock, (const sockaddr*)&PipeAddr, sizeof(PipeAddr));
if (err == 0) {
return true;
}
2017-07-27 23:09:05 +01:00
}
2017-07-28 00:02:47 +01:00
self->Close();
return false;
2017-07-13 18:08:14 +01:00
}
2017-07-27 23:09:05 +01:00
bool BaseConnection::Close()
2017-07-13 18:08:14 +01:00
{
2017-07-27 23:09:05 +01:00
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
if (self->sock == -1) {
return false;
}
close(self->sock);
self->sock = -1;
return true;
2017-07-13 18:08:14 +01:00
}
2017-07-27 23:09:05 +01:00
bool BaseConnection::Write(const void* data, size_t length)
2017-07-13 18:08:14 +01:00
{
2017-07-27 23:09:05 +01:00
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
if (self->sock == -1) {
return false;
}
ssize_t sentBytes = send(self->sock, data, length, 0);
return sentBytes == (ssize_t)length;
2017-07-13 18:08:14 +01:00
}
2017-07-27 23:09:05 +01:00
bool BaseConnection::Read(void* data, size_t length)
2017-07-13 18:08:14 +01:00
{
2017-07-27 23:09:05 +01:00
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
if (self->sock == -1) {
return false;
}
int res = recv(self->sock, data, length, 0);
return res == (int)length;
2017-07-13 18:08:14 +01:00
}