summaryrefslogtreecommitdiffstats
path: root/mcop/unixserver.cc
diff options
context:
space:
mode:
Diffstat (limited to 'mcop/unixserver.cc')
-rw-r--r--mcop/unixserver.cc151
1 files changed, 151 insertions, 0 deletions
diff --git a/mcop/unixserver.cc b/mcop/unixserver.cc
new file mode 100644
index 0000000..65cfa76
--- /dev/null
+++ b/mcop/unixserver.cc
@@ -0,0 +1,151 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include <config.h>
+#include "mcoputils.h"
+#include "unixserver.h"
+#include "socketconnection.h"
+#include "dispatcher.h"
+#include "debug.h"
+#define queue cqueue
+#include <arpa/inet.h>
+#undef queue
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+
+using namespace std;
+using namespace Arts;
+
+bool UnixServer::running()
+{
+ return socketOk;
+}
+
+UnixServer::UnixServer(Dispatcher *dispatcher, const string& serverID)
+{
+ this->dispatcher = dispatcher;
+
+ socketOk = initSocket(serverID);
+ if(socketOk) {
+ IOManager *iom = dispatcher->ioManager();
+ iom->watchFD(theSocket,IOType::read|IOType::except,this);
+ }
+}
+
+UnixServer::~UnixServer()
+{
+ if(socketOk) {
+ IOManager *iom = dispatcher->ioManager();
+ iom->remove(this,IOType::read|IOType::except);
+ close(theSocket);
+ unlink(xserverpath.c_str());
+ }
+}
+
+bool UnixServer::initSocket(const string& serverID)
+{
+ struct sockaddr_un socket_addr;
+
+ theSocket = socket(PF_UNIX,SOCK_STREAM,0);
+ if(theSocket < 0)
+ {
+ arts_warning("MCOP UnixServer: can't create a socket");
+ return false;
+ }
+
+ if(fcntl(theSocket,F_SETFL,O_NONBLOCK)<0)
+ {
+ arts_warning("MCOP UnixServer: can't initialize non blocking I/O");
+ close(theSocket);
+ return false;
+ }
+
+ int maxlen = sizeof(socket_addr.sun_path);
+ string pathname = MCOPUtils::createFilePath(serverID);
+
+ socket_addr.sun_family = AF_UNIX;
+ strncpy(socket_addr.sun_path,pathname.c_str(),maxlen);
+ socket_addr.sun_path[maxlen-1] = 0;
+
+ xserverpath = socket_addr.sun_path;
+
+ if ( bind( theSocket, (struct sockaddr *) &socket_addr,
+ sizeof(struct sockaddr_un) ) < 0 )
+ {
+ arts_warning("MCOP UnixServer: can't bind to file \"%s\"",
+ pathname.c_str());
+ close(theSocket);
+ return false;
+ }
+
+ if(listen(theSocket,16) < 0)
+ {
+ arts_warning("MCOP UnixServer: can't listen on the socket");
+ close(theSocket);
+ return false;
+ }
+ return true;
+}
+
+string UnixServer::url()
+{
+ return string("unix:") + xserverpath;
+}
+
+void UnixServer::notifyIO(int fd, int types)
+{
+ assert(fd == theSocket);
+ assert(socketOk);
+
+ arts_debug("UnixManager: got notifyIO");
+ if(types & IOType::read)
+ {
+ int clientfd;
+ struct sockaddr_un incoming;
+ socklen_t size_in = sizeof(struct sockaddr_un);
+
+ clientfd = accept(theSocket, (struct sockaddr*) &incoming, &size_in );
+ if(clientfd > 0)
+ {
+ // non blocking I/O
+ int flags = fcntl (fd, F_GETFL, 0);
+ assert (flags != -1);
+
+ int nbl_result = fcntl (fd, F_SETFL, flags | O_NONBLOCK);
+ assert(nbl_result >= 0);
+
+ Dispatcher::the()->initiateConnection(
+ new SocketConnection(clientfd));
+ }
+ }
+ arts_assert((types & IOType::write) == 0);
+ arts_assert((types & IOType::except) == 0);
+}