about summary refs log tree commit diff
path: root/src/engine/shared/fifoconsole.cpp
diff options
context:
space:
mode:
authordef <dennis@felsin9.de>2015-08-14 23:15:42 +0200
committerdef <dennis@felsin9.de>2015-08-14 23:15:42 +0200
commit47e5064885a6dc700196e70aa28372b1d2bb6781 (patch)
treec87053af46041f8e0a0043f7606cd20c164ae80a /src/engine/shared/fifoconsole.cpp
parent84039565f26749a202a2e321bfcdd416c47b0559 (diff)
downloadzcatch-47e5064885a6dc700196e70aa28372b1d2bb6781.tar.gz
zcatch-47e5064885a6dc700196e70aa28372b1d2bb6781.zip
Add fifo console support for server (from DDNet)
Diffstat (limited to 'src/engine/shared/fifoconsole.cpp')
-rw-r--r--src/engine/shared/fifoconsole.cpp91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/engine/shared/fifoconsole.cpp b/src/engine/shared/fifoconsole.cpp
new file mode 100644
index 00000000..e031b142
--- /dev/null
+++ b/src/engine/shared/fifoconsole.cpp
@@ -0,0 +1,91 @@
+#include "fifoconsole.h"
+
+#if defined(CONF_FAMILY_UNIX)
+
+#include <engine/shared/config.h>
+
+#include <fstream>
+
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+static LOCK gs_FifoLock = 0;
+static volatile bool gs_stopFifoThread = false;
+
+FifoConsole::FifoConsole(IConsole *pConsole, char *pFifoFile, int flag)
+{
+	m_pFifoFile = pFifoFile;
+	if(m_pFifoFile[0] == '\0')
+		return;
+
+	gs_stopFifoThread = false;
+	if(gs_FifoLock == 0)
+		gs_FifoLock = lock_create();
+
+	m_pFifoThread = thread_create(ListenFifoThread, this);
+	m_pConsole = pConsole;
+	m_flag = flag;
+
+	pthread_detach((pthread_t)m_pFifoThread);
+}
+
+FifoConsole::~FifoConsole()
+{
+	if(m_pFifoFile[0] == '\0')
+		return;
+
+	lock_wait(gs_FifoLock);
+	gs_stopFifoThread = true;
+	lock_release(gs_FifoLock);
+	gs_FifoLock = 0;
+}
+
+void FifoConsole::ListenFifoThread(void *pUser)
+{
+	FifoConsole *pData = (FifoConsole *)pUser;
+
+	if(!gs_FifoLock)
+	{
+		dbg_msg("fifo", "FIFO not properly initialized");
+		exit(2);
+	}
+
+	lock_wait(gs_FifoLock);
+	if(gs_stopFifoThread)
+		return;
+
+	mkfifo(pData->m_pFifoFile, 0600);
+
+	struct stat attribute;
+	stat(pData->m_pFifoFile, &attribute);
+
+	if(!S_ISFIFO(attribute.st_mode))
+	{
+		dbg_msg("fifo", "'%s' is not a FIFO, removing", pData->m_pFifoFile);
+		fs_remove(pData->m_pFifoFile);
+		mkfifo(pData->m_pFifoFile, 0600);
+		stat(pData->m_pFifoFile, &attribute);
+
+		if(!S_ISFIFO(attribute.st_mode))
+		{
+			dbg_msg("fifo", "Can't remove file, quitting");
+			exit(2);
+		}
+	}
+
+	lock_release(gs_FifoLock);
+
+	std::ifstream f;
+	char aBuf[8192];
+
+	while (true)
+	{
+		f.open(pData->m_pFifoFile);
+		while (f.getline(aBuf, sizeof(aBuf)))
+			pData->m_pConsole->ExecuteLineFlag(aBuf, pData->m_flag);
+		f.close();
+	}
+}
+#endif