فهرست منبع

UI: Detect other instances of obs on Linux

fixes: obsproject#3053
Christian Lockley 5 سال پیش
والد
کامیت
ad528bef17
3فایلهای تغییر یافته به همراه67 افزوده شده و 0 حذف شده
  1. 2 0
      UI/obs-app.cpp
  2. 62 0
      UI/platform-x11.cpp
  3. 3 0
      UI/platform.hpp

+ 2 - 0
UI/obs-app.cpp

@@ -1941,6 +1941,8 @@ static int run_program(fstream &logFile, int argc, char *argv[])
 		RunOnceMutex rom = GetRunOnceMutex(already_running);
 #elif defined(__APPLE__)
 		CheckAppWithSameBundleID(already_running);
+#elif defined(__linux__)
+		RunningInstanceCheck(already_running);
 #endif
 
 		if (!already_running) {

+ 62 - 0
UI/platform-x11.cpp

@@ -27,8 +27,70 @@
 #include <locale.h>
 
 #include "platform.hpp"
+
+#ifdef __linux__
+#include <sys/socket.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <sys/un.h>
+#endif
+
 using namespace std;
 
+#ifdef __linux__
+void RunningInstanceCheck(bool &already_running)
+{
+	int uniq = socket(AF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+
+	if (uniq == -1) {
+		blog(LOG_ERROR,
+		     "Failed to check for running instance, socket: %d", errno);
+		already_running = 0;
+		return;
+	}
+
+	struct sockaddr_un bindInfo;
+	memset(&bindInfo, 0, sizeof(sockaddr_un));
+	bindInfo.sun_family = AF_LOCAL;
+	char *abstactSockName = NULL;
+	asprintf(&abstactSockName, "%s %d %s", "/com/obsproject", getpid(),
+		 App()->GetVersionString().c_str());
+	memmove(bindInfo.sun_path + 1, abstactSockName,
+		strlen(abstactSockName));
+	free(abstactSockName);
+
+	int bindErr = bind(uniq, (struct sockaddr *)&bindInfo,
+			   sizeof(struct sockaddr_un));
+	already_running = bindErr == 0 ? 0 : 1;
+
+	if (already_running) {
+		return;
+	}
+
+	FILE *fp = fopen("/proc/net/unix", "re");
+
+	if (fp == NULL) {
+		return;
+	}
+
+	char *line = NULL;
+	size_t n = 0;
+	int obsCnt = 0;
+	while (getdelim(&line, &n, ' ', fp) != EOF) {
+		line[strcspn(line, "\n")] = '\0';
+		if (*line == '@') {
+			if (strstr(line, "@/com/obsproject") != NULL) {
+				++obsCnt;
+			}
+		}
+	}
+	already_running = obsCnt == 1 ? 0 : 1;
+	free(line);
+	fclose(fp);
+}
+#endif
+
 static inline bool check_path(const char *data, const char *path,
 			      string &output)
 {

+ 3 - 0
UI/platform.hpp

@@ -70,3 +70,6 @@ void InstallNSApplicationSubclass();
 void disableColorSpaceConversion(QWidget *window);
 void CheckAppWithSameBundleID(bool &already_running);
 #endif
+#ifdef __linux__
+void RunningInstanceCheck(bool &already_running);
+#endif