]> git.lyx.org Git - lyx.git/blobdiff - src/support/forkedcall.C
split LyXText::rowlist_ into individual Paragraph::rows_ chunks
[lyx.git] / src / support / forkedcall.C
index 6eadbc4c08f18e79b2ac244a328724566aa42b57..4853e4c21a2f4f589e09d6903396e0347f46c3a4 100644 (file)
@@ -1,5 +1,5 @@
 /**
- *  \file forkedcall.C
+ * \file forkedcall.C
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
 
 #include <config.h>
 
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
 #include "forkedcall.h"
 #include "forkedcontr.h"
 #include "lstrings.h"
@@ -52,6 +48,9 @@ using std::endl;
 using std::strerror;
 #endif
 
+namespace lyx {
+namespace support {
+
 
 namespace {
 
@@ -63,7 +62,7 @@ public:
                if (secs > 0) {
                        new Murder(secs, pid);
                } else if (pid != 0) {
-                       lyx::kill(pid, SIGKILL);
+                       lyx::support::kill(pid, SIGKILL);
                }
        }
 
@@ -71,7 +70,7 @@ public:
        void kill()
        {
                if (pid_ != 0) {
-                       lyx::kill(pid_, SIGKILL);
+                       lyx::support::kill(pid_, SIGKILL);
                }
                lyxerr << "Killed " << pid_ << std::endl;
                delete this;
@@ -115,7 +114,7 @@ void ForkedProcess::emitSignal()
 
 
 // Wait for child process to finish.
-int ForkedProcess::runBlocking() 
+int ForkedProcess::runBlocking()
 {
        retval_  = 0;
        pid_ = generateChild();
@@ -147,9 +146,27 @@ int ForkedProcess::runNonBlocking()
        return retval_;
 }
 
+
+bool ForkedProcess::running() const
+{
+       if (!pid())
+               return false;
+
+       // Un-UNIX like, but we don't have much use for
+       // knowing if a zombie exists, so just reap it first.
+       int waitstatus;
+       waitpid(pid(), &waitstatus, WNOHANG);
+
+       // Racy of course, but it will do.
+       if (::kill(pid(), 0) && errno == ESRCH)
+               return false;
+       return true;
+}
+
+
 void ForkedProcess::kill(int tol)
 {
-       lyxerr << "ForkedProcess::kill(" << tol << ")" << std::endl;
+       lyxerr << "ForkedProcess::kill(" << tol << ')' << endl;
        if (pid() == 0) {
                lyxerr << "Can't kill non-existent process!" << endl;
                return;
@@ -161,7 +178,7 @@ void ForkedProcess::kill(int tol)
                Murder::killItDead(0, pid());
 
        } else {
-               int ret = lyx::kill(pid(), SIGHUP);
+               int ret = lyx::support::kill(pid(), SIGHUP);
 
                // The process is already dead if wait_for_death is false
                bool const wait_for_death = (ret == 0 && errno != ESRCH);
@@ -235,53 +252,40 @@ int Forkedcall::startscript(string const & what, SignalTypePtr signal)
 // generate child in background
 int Forkedcall::generateChild()
 {
-       const int MAX_ARGV = 255;
-       char *syscmd = 0;
+       // Split command_ up into a char * array
+       int const MAX_ARGV = 255;
        char *argv[MAX_ARGV];
 
-       string childcommand(command_); // copy
-       bool more = true;
-       string rest = split(command_, childcommand, ' ');
-
-       int  index = 0;
-       while (more) {
-               childcommand = ltrim(childcommand);
-               if (syscmd == 0) {
-                       syscmd = new char[childcommand.length() + 1];
-                       childcommand.copy(syscmd, childcommand.length());
-                       syscmd[childcommand.length()] = '\0';
-               }
-               if (!childcommand.empty()) {
-                       char * tmp = new char[childcommand.length() + 1];
-                       childcommand.copy(tmp, childcommand.length());
-                       tmp[childcommand.length()] = '\0';
-                       argv[index++] = tmp;
-               }
+       string line = command_;
+       int index = 0;
+       for (; index < MAX_ARGV-1; ++index) {
+               string word;
+               line = split(line, word, ' ');
+               if (word.empty())
+                       break;
 
-               // reinit
-               more = !rest.empty();
-               if (more)
-                       rest = split(rest, childcommand, ' ');
+               char * tmp = new char[word.length() + 1];
+               word.copy(tmp, word.length());
+               tmp[word.length()] = '\0';
+
+               argv[index] = tmp;
        }
        argv[index] = 0;
 
 #ifndef __EMX__
-       pid_t cpid = ::fork();
+       pid_t const cpid = ::fork();
        if (cpid == 0) {
                // Child
-               execvp(syscmd, argv);
+               execvp(argv[0], argv);
+
                // If something goes wrong, we end up here
-               string args;
-               int i = 0;
-               while (argv[i] != 0)
-                       args += string(" ") + argv[i++];
-               lyxerr << "execvp of \"" << syscmd << args << "\" failed: "
+               lyxerr << "execvp of \"" << command_ << "\" failed: "
                       << strerror(errno) << endl;
                _exit(1);
        }
 #else
-       pid_t cpid = spawnvp(P_SESSION|P_DEFAULT|P_MINIMIZE|P_BACKGROUND,
-                            syscmd, argv);
+       pid_t const cpid = spawnvp(P_SESSION|P_DEFAULT|P_MINIMIZE|P_BACKGROUND,
+                                  argv[0], argv);
 #endif
 
        if (cpid < 0) {
@@ -290,7 +294,6 @@ int Forkedcall::generateChild()
        }
 
        // Clean-up.
-       delete [] syscmd;
        for (int i = 0; i < MAX_ARGV; ++i) {
                if (argv[i] == 0)
                        break;
@@ -299,3 +302,6 @@ int Forkedcall::generateChild()
 
        return cpid;
 }
+
+} // namespace support
+} // namespace lyx