summaryrefslogtreecommitdiff
path: root/trunk/qpid/cpp/src/qpid/broker/Daemon.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/qpid/cpp/src/qpid/broker/Daemon.cpp')
-rw-r--r--trunk/qpid/cpp/src/qpid/broker/Daemon.cpp219
1 files changed, 0 insertions, 219 deletions
diff --git a/trunk/qpid/cpp/src/qpid/broker/Daemon.cpp b/trunk/qpid/cpp/src/qpid/broker/Daemon.cpp
deleted file mode 100644
index b30e5f18cb..0000000000
--- a/trunk/qpid/cpp/src/qpid/broker/Daemon.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- *
- * Copyright (c) 2006 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/*
- * TODO: Note this is really a Posix specific implementation and so should be
- * refactored together with windows/QpiddBroker into a more coherent daemon driver/
- * platform specific split
- */
-#include "qpid/broker/Daemon.h"
-#include "qpid/log/Statement.h"
-#include "qpid/Exception.h"
-#include "qpid/sys/posix/PidFile.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-namespace qpid {
-namespace broker {
-
-using namespace std;
-using qpid::sys::PidFile;
-
-Daemon::Daemon(std::string _pidDir) : pidDir(_pidDir) {
- struct stat s;
- pid = -1;
- pipeFds[0] = pipeFds[1] = -1;
-
- if (::stat(pidDir.c_str(), &s)) {
- if (errno == ENOENT) {
- if (::mkdir(pidDir.c_str(), 0755))
- throw Exception ("Can't create PID directory: " + pidDir);
- }
- else
- throw Exception ("PID directory not found: " + pidDir);
- }
-}
-
-string Daemon::pidFile(string pidDir, uint16_t port) {
- ostringstream path;
- path << pidDir << "/qpidd." << port << ".pid";
- return path.str();
-}
-
-/*
- * Rewritten using low-level IO, for compatibility
- * with earlier Boost versions, i.e. 103200.
- */
-void Daemon::fork()
-{
- if(::pipe(pipeFds) < 0) throw ErrnoException("Can't create pipe");
- if ((pid = ::fork()) < 0) throw ErrnoException("Daemon fork failed");
- if (pid == 0) { // Child
- try {
- QPID_LOG(debug, "Forked daemon child process");
-
- // File descriptors
- if(::close(pipeFds[0])<0) throw ErrnoException("Cannot close read pipe");
- if(::close(0)<0) throw ErrnoException("Cannot close stdin");
- if(::close(1)<0) throw ErrnoException("Cannot close stdout");
- if(::close(2)<0) throw ErrnoException("Cannot close stderr");
- int fd=::open("/dev/null",O_RDWR); // stdin
- if(fd != 0) throw ErrnoException("Cannot re-open stdin");
- if(::dup(fd)<0) throw ErrnoException("Cannot re-open stdout");
- if(::dup(fd)<0) throw ErrnoException("Cannot re-open stderror");
-
- // Misc
- if(setsid()<0) throw ErrnoException("Cannot set session ID");
- if(chdir(pidDir.c_str()) < 0) throw ErrnoException("Cannot change directory to "+pidDir);
- umask(027);
-
- // Child behavior
- child();
- }
- catch (const exception& e) {
- QPID_LOG(critical, "Unexpected error: " << e.what());
- uint16_t port = 0;
- int unused_ret; //Supress warning about ignoring return value.
- unused_ret = write(pipeFds[1], &port, sizeof(uint16_t));
-
- std::string pipeFailureMessage = e.what();
- unused_ret = write ( pipeFds[1],
- pipeFailureMessage.c_str(),
- strlen(pipeFailureMessage.c_str())
- );
- }
- }
- else { // Parent
- close(pipeFds[1]); // Write side.
- parent();
- }
-}
-
-Daemon::~Daemon() {
- if (!lockFile.empty())
- unlink(lockFile.c_str());
-}
-
-uint16_t Daemon::wait(int timeout) { // parent waits for child.
- try {
- errno = 0;
- struct timeval tv;
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
-
- /*
- * Rewritten using low-level IO, for compatibility
- * with earlier Boost versions, i.e. 103200.
- */
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(pipeFds[0], &fds);
- int n=select(FD_SETSIZE, &fds, 0, 0, &tv);
- if(n==0) throw Exception("Timed out waiting for daemon (If store recovery is in progress, use longer wait time)");
- if(n<0) throw ErrnoException("Error waiting for daemon");
- uint16_t port = 0;
- /*
- * Read the child's port number from the pipe.
- */
- int desired_read = sizeof(uint16_t);
- if ( desired_read > ::read(pipeFds[0], & port, desired_read) )
- throw Exception("Cannot read from child process.");
-
- /*
- * If the port number is 0, the child has put an error message
- * on the pipe. Get it and throw it.
- */
- if ( 0 == port ) {
- // Skip whitespace
- char c = ' ';
- while ( isspace(c) ) {
- if ( 1 > ::read(pipeFds[0], &c, 1) )
- throw Exception("Child port == 0, and no error message on pipe.");
- }
-
- // Get Message
- string errmsg;
- do {
- errmsg += c;
- } while (::read(pipeFds[0], &c, 1));
- throw Exception("Daemon startup failed"+
- (errmsg.empty() ? string(".") : ": " + errmsg));
- }
- return port;
- }
- catch (const std::exception& e) {
- // Print directly to cerr. The caller will catch and log the
- // exception, but in the case of a daemon parent process we
- // also need to be sure the error goes to stderr. A
- // dameon's logging configuration normally does not log to
- // stderr.
- std::cerr << e.what() << endl;
- throw;
- }
-}
-
-
-/*
- * When the child is ready, it writes its pid to the
- * lockfile and its port number on the pipe back to
- * its parent process. This indicates that the
- * child has successfully daemonized. When the parent
- * hears the good news, it ill exit.
- */
-void Daemon::ready(uint16_t port) { // child
- lockFile = pidFile(pidDir, port);
- PidFile lf(lockFile, true);
-
- /*
- * Write the PID to the lockfile.
- */
- lf.writePid();
-
- /*
- * Write the port number to the parent.
- */
- int desired_write = sizeof(uint16_t);
- if ( desired_write > ::write(pipeFds[1], & port, desired_write) ) {
- throw Exception("Error writing to parent." );
- }
-
- QPID_LOG(debug, "Daemon ready on port: " << port);
-}
-
-/*
- * The parent process reads the child's pid
- * from the lockfile.
- */
-pid_t Daemon::getPid(string _pidDir, uint16_t port) {
- string name = pidFile(_pidDir, port);
- PidFile lf(name, false);
- pid_t pid = lf.readPid();
- if (kill(pid, 0) < 0 && errno != EPERM) {
- unlink(name.c_str());
- throw Exception("Removing stale lock file "+name);
- }
- return pid;
-}
-
-
-}} // namespace qpid::broker