summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorMarc Laukien <marc@zeroc.com>2002-01-27 15:57:39 +0000
committerMarc Laukien <marc@zeroc.com>2002-01-27 15:57:39 +0000
commitec78bffd77b2400bcb862c8d68ce4a2d7fa26272 (patch)
tree8ef8f07b9e2a4ef649fbccb4f3bc886e5affb92c /cpp/src
parentstarted with glacier test (diff)
downloadice-ec78bffd77b2400bcb862c8d68ce4a2d7fa26272.tar.bz2
ice-ec78bffd77b2400bcb862c8d68ce4a2d7fa26272.tar.xz
ice-ec78bffd77b2400bcb862c8d68ce4a2d7fa26272.zip
added missing files
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Glacier/GlacierI.cpp201
-rw-r--r--cpp/src/Glacier/GlacierI.h35
2 files changed, 236 insertions, 0 deletions
diff --git a/cpp/src/Glacier/GlacierI.cpp b/cpp/src/Glacier/GlacierI.cpp
new file mode 100644
index 00000000000..0d2ef4a4c2c
--- /dev/null
+++ b/cpp/src/Glacier/GlacierI.cpp
@@ -0,0 +1,201 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/UUID.h>
+#include <Glacier/GlacierI.h>
+#include <fcntl.h>
+//#include <sys/wait.h>
+
+#ifdef WIN32
+# error Sorry, the glacier starter is not yet supported on WIN32.
+#endif
+
+using namespace std;
+using namespace Ice;
+using namespace Glacier;
+
+Glacier::StarterI::StarterI(const CommunicatorPtr& communicator) :
+ _communicator(communicator)
+{
+}
+
+RouterPrx
+Glacier::StarterI::startRouter(const string& userId, const string& password, const Current&)
+{
+ //
+ // TODO: userId/password check
+ //
+
+ //
+ // Start a router
+ //
+ string uuid = IceUtil::generateUUID();
+ char buf[4*1024];
+ try
+ {
+ int fds[2];
+ if (pipe(fds) != 0)
+ {
+ SystemException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+ pid_t pid = fork();
+ if (pid == -1)
+ {
+ SystemException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+ if (pid == 0) // Child process
+ {
+ //
+ // Close all filedescriptors, except for standard input,
+ // standard output, standard error output, and the write side
+ // of the newly created pipe.
+ //
+ int maxFd = static_cast<int>(sysconf(_SC_OPEN_MAX));
+ for (int fd = 3; fd < maxFd; ++fd)
+ {
+ if (fd != fds[1])
+ {
+ close(fd);
+ }
+ }
+
+ //
+ // Setup arguments to start the router with.
+ //
+ StringSeq args = _communicator->getProperties()->getCommandLineOptions();
+ args.push_back("--Glacier.Router.Identity=" + uuid);
+ ostringstream s;
+ s << "--Glacier.Router.PrintProxyOnFd=" << fds[1];
+ args.push_back(s.str());
+
+ //
+ // Convert to standard argc/argv.
+ //
+ int argc = args.size() + 1;
+ char** argv = static_cast<char**>(malloc((argc + 1) * sizeof(char*)));
+ StringSeq::iterator p;
+ int i;
+ for (p = args.begin(), i = 1; p != args.end(); ++p, ++i)
+ {
+ assert(i < argc);
+ argv[i] = strdup(p->c_str());
+ }
+ assert(i == argc);
+ argv[0] = strdup("glacier"); // TODO: Property
+ argv[argc] = 0;
+
+ //
+ // Try to start the router.
+ //
+ if (execvp(argv[0], argv) == -1)
+ {
+ //
+ // Send any errors to the parent process, using the write
+ // end of the pipe.
+ //
+ ostringstream s;
+ s << "can't execute `" << argv[0] << "': " << strerror(errno);
+ write(fds[1], s.str().c_str(), s.str().length());
+ close(fds[1]);
+ exit(EXIT_FAILURE);
+ }
+ }
+ else // Parent process
+ {
+ //
+ // Close the write side of the newly created pipe
+ //
+ close(fds[1]);
+
+ //
+ // Wait until data can be read from the newly started router,
+ // with timeout.
+ //
+ int flags = fcntl(fds[0], F_GETFL);
+ flags |= O_NONBLOCK;
+ if (fcntl(fds[0], F_SETFL, flags) == -1)
+ {
+ SystemException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+
+ repeatSelect:
+ fd_set fdSet;
+ FD_ZERO(&fdSet);
+ FD_SET(fds[0], &fdSet);
+ struct timeval tv;
+ tv.tv_sec = 5; // TODO: Property
+ tv.tv_usec = 0;
+ int ret = ::select(fds[0] + 1, &fdSet, 0, 0, &tv);
+
+ if (ret == -1)
+ {
+ if (errno == EINTR)
+ {
+ goto repeatSelect;
+ }
+
+ SystemException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+
+ if (ret == 0) // Timeout
+ {
+ assert(false); // TODO: Handle this situation.
+ }
+
+ assert(FD_ISSET(fds[0], &fdSet));
+
+ //
+ // Read the response
+ //
+ ssize_t sz = read(fds[0], buf, sizeof(buf)/sizeof(char) - 1);
+ if(sz == -1)
+ {
+ SystemException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+ assert(sz != 0); // TODO: Handle EOF
+ buf[sz] = '\0'; // Terminate the string we got back.
+ }
+ }
+ catch(const LocalException& ex)
+ {
+ // TODO: Log exception or print warning
+ cerr << ex << endl;
+ ex.ice_throw();
+ }
+
+ if (strncmp(buf, uuid.c_str(), uuid.length()) == 0)
+ {
+ //
+ // We got the stringified router proxy.
+ //
+ return RouterPrx::uncheckedCast(_communicator->stringToProxy(buf));
+ }
+ else
+ {
+ //
+ // We got something else.
+ //
+ CannotStartRouterException ex;
+ ex.reason = buf;
+ // TODO: Log exception.
+ cerr << ex << endl;
+ throw ex;
+ }
+}
diff --git a/cpp/src/Glacier/GlacierI.h b/cpp/src/Glacier/GlacierI.h
new file mode 100644
index 00000000000..34bbddb26be
--- /dev/null
+++ b/cpp/src/Glacier/GlacierI.h
@@ -0,0 +1,35 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef GLACIER_GLACIER_I_H
+#define GLACIER_GLACIER_I_H
+
+#include <Ice/Ice.h>
+#include <Glacier/Glacier.h>
+
+namespace Glacier
+{
+
+class StarterI : public Starter
+{
+public:
+
+ StarterI(const Ice::CommunicatorPtr&);
+
+ Ice::RouterPrx startRouter(const std::string&, const std::string&, const Ice::Current&);
+
+private:
+
+ Ice::CommunicatorPtr _communicator;
+};
+
+}
+
+#endif