aboutsummaryrefslogtreecommitdiff
path: root/externals/discord-rpc/src/connection_unix.cpp
diff options
context:
space:
mode:
authorDawid Potocki <dawid@dawidpotocki.com>2024-03-05 14:09:27 +1300
committerDawid Potocki <dawid@dawidpotocki.com>2024-03-05 20:34:15 +1300
commit063e15900bda8453fb0fc6751e78d064501ccbae (patch)
treea4cd5f01dbca33a262333aff10e1e035217a30c8 /externals/discord-rpc/src/connection_unix.cpp
parent537296095ab24eddcb196b5ef98004f91de9c8c2 (diff)
Replace broken submodules with vendored source codeHEADpatched
Diffstat (limited to 'externals/discord-rpc/src/connection_unix.cpp')
-rw-r--r--externals/discord-rpc/src/connection_unix.cpp125
1 files changed, 125 insertions, 0 deletions
diff --git a/externals/discord-rpc/src/connection_unix.cpp b/externals/discord-rpc/src/connection_unix.cpp
new file mode 100644
index 0000000000..85dace3ccc
--- /dev/null
+++ b/externals/discord-rpc/src/connection_unix.cpp
@@ -0,0 +1,125 @@
+#include "connection.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+int GetProcessId()
+{
+ return ::getpid();
+}
+
+struct BaseConnectionUnix : public BaseConnection {
+ int sock{-1};
+};
+
+static BaseConnectionUnix Connection;
+static sockaddr_un PipeAddr{};
+#ifdef MSG_NOSIGNAL
+static int MsgFlags = MSG_NOSIGNAL;
+#else
+static int MsgFlags = 0;
+#endif
+
+static const char* GetTempPath()
+{
+ 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*/ BaseConnection* BaseConnection::Create()
+{
+ PipeAddr.sun_family = AF_UNIX;
+ return &Connection;
+}
+
+/*static*/ void BaseConnection::Destroy(BaseConnection*& c)
+{
+ auto self = reinterpret_cast<BaseConnectionUnix*>(c);
+ self->Close();
+ c = nullptr;
+}
+
+bool BaseConnection::Open()
+{
+ const char* tempPath = GetTempPath();
+ 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);
+#ifdef SO_NOSIGPIPE
+ int optval = 1;
+ setsockopt(self->sock, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval));
+#endif
+
+ 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) {
+ self->isOpen = true;
+ return true;
+ }
+ }
+ self->Close();
+ return false;
+}
+
+bool BaseConnection::Close()
+{
+ auto self = reinterpret_cast<BaseConnectionUnix*>(this);
+ if (self->sock == -1) {
+ return false;
+ }
+ close(self->sock);
+ self->sock = -1;
+ self->isOpen = false;
+ return true;
+}
+
+bool BaseConnection::Write(const void* data, size_t length)
+{
+ auto self = reinterpret_cast<BaseConnectionUnix*>(this);
+
+ if (self->sock == -1) {
+ return false;
+ }
+
+ ssize_t sentBytes = send(self->sock, data, length, MsgFlags);
+ if (sentBytes < 0) {
+ Close();
+ }
+ return sentBytes == (ssize_t)length;
+}
+
+bool BaseConnection::Read(void* data, size_t length)
+{
+ auto self = reinterpret_cast<BaseConnectionUnix*>(this);
+
+ if (self->sock == -1) {
+ return false;
+ }
+
+ int res = (int)recv(self->sock, data, length, MsgFlags);
+ if (res < 0) {
+ if (errno == EAGAIN) {
+ return false;
+ }
+ Close();
+ }
+ else if (res == 0) {
+ Close();
+ }
+ return res == (int)length;
+}