]> git.lyx.org Git - lyx.git/blobdiff - src/support/forkedcontr.C
make "make distcheck" work
[lyx.git] / src / support / forkedcontr.C
index 9a35444df4340e57bb25edcfc71e86792fe2d9e4..a869bdc909b810d6012a8d9814d7c90107f22602 100644 (file)
 
 #include <config.h>
 
-#include "forkedcontr.h"
-#include "forkedcall.h"
-#include "lyxfunctional.h"
+#include "support/forkedcontr.h"
+#include "support/forkedcall.h"
 
 #include "debug.h"
 
-#include <boost/iterator/indirect_iterator.hpp>
+#include <boost/bind.hpp>
 
 #include <cerrno>
 #include <cstdlib>
-#include <unistd.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
 #include <sys/wait.h>
 
+using boost::bind;
+
 using std::endl;
+using std::equal_to;
 using std::find_if;
 
 using std::string;
@@ -163,6 +167,12 @@ extern "C"
 void child_handler(int)
 {
        ForkedcallsController & fcc = ForkedcallsController::get();
+
+       // Be safe
+       typedef vector<ForkedcallsController::Data>::size_type size_type;
+       if (size_type(fcc.current_child + 1) >= fcc.reaped_children.size())
+               return;
+
        ForkedcallsController::Data & store =
                fcc.reaped_children[++fcc.current_child];
        // Clean up the child process.
@@ -216,16 +226,13 @@ void ForkedcallsController::addCall(ForkedProcess const & newcall)
 }
 
 
-ForkedcallsController::iterator ForkedcallsController::find_pid(pid_t pid)
+ForkedcallsController::iterator
+ ForkedcallsController::find_pid(pid_t pid)
 {
-       typedef boost::indirect_iterator<ListType::iterator> iterator;
-
-       iterator begin = boost::make_indirect_iterator(forkedCalls.begin());
-       iterator end   = boost::make_indirect_iterator(forkedCalls.end());
-       iterator it = find_if(begin, end,
-                             lyx::compare_memfun(&Forkedcall::pid, pid));
-
-       return it.base();
+       return find_if(forkedCalls.begin(), forkedCalls.end(),
+                      bind(equal_to<pid_t>(),
+                           bind(&Forkedcall::pid, _1),
+                           pid));
 }
 
 
@@ -251,29 +258,34 @@ void ForkedcallsController::handleCompletedProcesses()
        // Block the SIGCHLD signal.
        sigprocmask(SIG_BLOCK, &newMask, &oldMask);
 
-       for (int i = 0; i != 1+current_child; ++i) {
+       for (int i = 0; i != 1 + current_child; ++i) {
                Data & store = reaped_children[i];
 
                if (store.pid == -1) {
-                       lyxerr << "LyX: Error waiting for child: "
-                              << strerror(errno) << endl;
+                       // Might happen perfectly innocently, eg as a result
+                       // of the system (3) call.
+                       if (errno)
+                               lyxerr << "LyX: Error waiting for child: "
+                                      << strerror(errno) << endl;
                        continue;
                }
 
                ListType::iterator it = find_pid(store.pid);
-               BOOST_ASSERT(it != forkedCalls.end());
+               if (it == forkedCalls.end())
+                       // Eg, child was run in blocking mode
+                       continue;
 
-               ForkedProcess & child = *it->get();
+               ListType::value_type child = (*it);
                bool remove_it = false;
 
                if (WIFEXITED(store.status)) {
                        // Ok, the return value goes into retval.
-                       child.setRetValue(WEXITSTATUS(store.status));
+                       child->setRetValue(WEXITSTATUS(store.status));
                        remove_it = true;
 
                } else if (WIFSIGNALED(store.status)) {
                        // Child died, so pretend it returned 1
-                       child.setRetValue(1);
+                       child->setRetValue(1);
                        remove_it = true;
 
                } else if (WIFSTOPPED(store.status)) {
@@ -284,15 +296,15 @@ void ForkedcallsController::handleCompletedProcesses()
 
                } else {
                        lyxerr << "LyX: Something rotten happened while "
-                               "waiting for child " << store.pid << endl;
+                              << "waiting for child " << store.pid << endl;
 
                        // Child died, so pretend it returned 1
-                       child.setRetValue(1);
+                       child->setRetValue(1);
                        remove_it = true;
                }
 
                if (remove_it) {
-                       child.emitSignal();
+                       child->emitSignal();
                        forkedCalls.erase(it);
                }
        }