-#include "syscontr.h"
-#include "support/lstrings.h"
-#include "support/lyxlib.h"
-#include "support/filetools.h"
-#include "support/os.h"
-
-using std::endl;
-
-#ifndef CXX_GLOBAL_CSTD
-using std::strerror;
-#endif
-
-
-Systemcalls::Systemcalls() {
- pid = 0; // No child yet
-}
-
-Systemcalls::Systemcalls(Starttype how, string const & what, Callbackfct cback)
-{
- startscript(how, what, cback);
-}
-
-Systemcalls::~Systemcalls() {
-#if 0
- // If the child is alive, we have to brutally kill it
- if (getpid() != 0) {
- lyx::kill(getpid(), SIGKILL);
- }
-#endif
-}
-
-// Start a childprocess
-//
-// if child runs in background, add information to global controller.
-
-int Systemcalls::startscript() {
- retval = 0;
- switch (start) {
- case System:
- case SystemDontWait:
- retval = ::system(command.c_str());
- callback();
- break;
- case Wait:
- pid = fork();
- if (pid>0) { // Fork succesful. Wait for child
- waitForChild();
- callback();
- } else
- retval = 1;
- break;
- case DontWait:
- pid = fork();
- if (pid>0) {
- // Now integrate into Controller
- SystemcallsSingletoncontroller::Startcontroller starter;
- SystemcallsSingletoncontroller * contr = starter.getController();
- // Add this to controller
- contr->addCall(*this);
- } else
- retval = 1;
- break;
- }
- return retval;
-}
-
-void Systemcalls::kill(int /*tolerance*/) {
- if (getpid() == 0) {
- lyxerr << "LyX: Can't kill non-existing process." << endl;
- return;
- }
- int ret = lyx::kill(getpid(), SIGHUP);
- bool wait_for_death = true;
- if (ret != 0) {
- if (errno == ESRCH) {
- // The process is already dead!
- wait_for_death = false;
- } else {
- // Something is rotten - maybe we lost permissions?
- }
- }
- if (wait_for_death) {
- // Here, we should add the PID to a list of
- // waiting processes to kill if they are not
- // dead within tolerance seconds
-
- // CHECK Implement this using the timer of
- // the singleton systemcontroller (Asger)
-
- }
-}
-
-
-// Wait for child process to finish. Returns returncode from child.
-void Systemcalls::waitForChild() {
- // We'll pretend that the child returns 1 on all errorconditions.
- retval = 1;
- int status;
- bool wait = true;
- while (wait) {
- pid_t waitrpid = waitpid(pid, &status, WUNTRACED);
- if (waitrpid == -1) {
- lyxerr << "LyX: Error waiting for child:"
- << strerror(errno) << endl;
- wait = false;
- } else if (WIFEXITED(status)) {
- // Child exited normally. Update return value.
- retval = WEXITSTATUS(status);
- wait = false;
- } else if (WIFSIGNALED(status)) {
- lyxerr << "LyX: Child didn't catch signal "
- << WTERMSIG(status)
- << "and died. Too bad." << endl;
- wait = false;
- } else if (WIFSTOPPED(status)) {
- lyxerr << "LyX: Child (pid: " << pid
- << ") stopped on signal "
- << WSTOPSIG(status)
- << ". Waiting for child to finish." << endl;
- } else {
- lyxerr << "LyX: Something rotten happened while "
- "waiting for child " << pid << endl;
- wait = false;
- }
- }
-}