summaryrefslogtreecommitdiff
path: root/src/pipeengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pipeengine.cpp')
-rw-r--r--src/pipeengine.cpp81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/pipeengine.cpp b/src/pipeengine.cpp
new file mode 100644
index 000000000..6a5b8c3af
--- /dev/null
+++ b/src/pipeengine.cpp
@@ -0,0 +1,81 @@
+/*
+ *
+ * (C) 2003-2012 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ */
+
+#include "services.h"
+#include "sockets.h"
+#include "socketengine.h"
+
+#ifndef _WIN32
+#include <fcntl.h>
+#endif
+
+Pipe::Pipe() : Socket(-1), write_pipe(-1)
+{
+ int fds[2];
+ if (pipe(fds))
+ throw CoreException("Could not create pipe: " + Anope::LastError());
+ int flags = fcntl(fds[0], F_GETFL, 0);
+ fcntl(fds[0], F_SETFL, flags | O_NONBLOCK);
+ flags = fcntl(fds[1], F_GETFL, 0);
+ fcntl(fds[1], F_SETFL, flags | O_NONBLOCK);
+
+ SocketEngine::Change(this, false, SF_READABLE);
+ SocketEngine::Change(this, false, SF_WRITABLE);
+ anope_close(this->sock);
+ this->io->Destroy();
+ SocketEngine::Sockets.erase(this->sock);
+
+ this->sock = fds[0];
+ this->write_pipe = fds[1];
+
+ SocketEngine::Sockets[this->sock] = this;
+ SocketEngine::Change(this, true, SF_READABLE);
+}
+
+Pipe::~Pipe()
+{
+ if (this->write_pipe >= 0)
+ anope_close(this->write_pipe);
+}
+
+bool Pipe::ProcessRead()
+{
+ this->OnNotify();
+
+ char dummy[512];
+ while (read(this->GetFD(), dummy, 512) == 512);
+ return true;
+}
+
+void Pipe::Write(const char *data, size_t sz)
+{
+ write(this->write_pipe, data, sz);
+}
+
+int Pipe::Read(char *data, size_t sz)
+{
+ return read(this->GetFD(), data, sz);
+}
+
+bool Pipe::SetWriteBlocking(bool state)
+{
+ int flags = fcntl(this->write_pipe, F_GETFL, 0);
+ if (state)
+ return !fcntl(this->write_pipe, F_SETFL, flags & ~O_NONBLOCK);
+ else
+ return !fcntl(this->write_pipe, F_SETFL, flags | O_NONBLOCK);
+}
+
+void Pipe::Notify()
+{
+ this->Write("\0", 1);
+}
+