]> git.lyx.org Git - lyx.git/blobdiff - src/support/syscall.C
lyx-devel.diff
[lyx.git] / src / support / syscall.C
index c5c99eadead36a5b089b2d9fedcefef51a35e616..46591cc82a7a5dcc52d6a0696e4f571c232b1a92 100644 (file)
@@ -4,37 +4,35 @@
 #pragma implementation
 #endif
 
-#include <errno.h>
+#include <cerrno>
 #include <sys/types.h>
 #include <sys/wait.h>
-#include <signal.h>
+#include <csignal>
 #include <cstdlib>
-#include <cstdio>
 #include <unistd.h>
 #include "debug.h"
 #include "syscall.h"
 #include "syscontr.h"
 #include "support/lstrings.h"
+#include "support/lyxlib.h"
+
+using std::endl;
+
 
 Systemcalls::Systemcalls() {
-       pid = (pid_t) 0; // No child yet
+       pid = 0; // No child yet
 }
 
 Systemcalls::Systemcalls(Starttype how, string const & what, Callbackfct cback)
 {
-       start   = how;
-       command = what;
-       cbk     = cback;
-       pid     = (pid_t) 0;
-       retval  = 0;
-       startscript();
+       startscript(how, what, cback);
 }
 
 Systemcalls::~Systemcalls() {
 #if 0
        // If the child is alive, we have to brutally kill it
        if (getpid() != 0) {
-               ::kill(getpid(), SIGKILL);
+               lyx::kill(getpid(), SIGKILL);
        }
 #endif
 }
@@ -47,7 +45,8 @@ int Systemcalls::startscript() {
        retval = 0;
        switch (start) {
        case System: 
-               retval = system(command.c_str());
+       case SystemDontWait:
+               retval = ::system(command.c_str());
                callback();
                break;
        case Wait:   
@@ -73,12 +72,12 @@ int Systemcalls::startscript() {
        return retval;
 }
 
-void Systemcalls::kill(int tolerance) {
+void Systemcalls::kill(int /*tolerance*/) {
        if (getpid() == 0) {
                lyxerr << "LyX: Can't kill non-existing process." << endl;
                return;
        }
-       int ret = ::kill(getpid(), SIGHUP);
+       int ret = lyx::kill(getpid(), SIGHUP);
        bool wait_for_death = true;
        if (ret != 0) {
                if (errno == ESRCH) {
@@ -91,8 +90,11 @@ void Systemcalls::kill(int tolerance) {
        if (wait_for_death) {
                // Here, we should add the PID to a list of
                // waiting processes to kill if they are not
-               // dead without tolerance seconds
-#warning Implement this using the timer of the singleton systemcontroller (Asger)
+               // dead within tolerance seconds
+
+               // CHECK Implement this using the timer of
+               // the singleton systemcontroller (Asger)
+
        }
 }
 
@@ -137,28 +139,34 @@ pid_t Systemcalls::fork()
 {
        pid_t cpid= ::fork();
        if (cpid == 0) { // child
+               // TODO: Consider doing all of this before the fork, otherwise me
+               // might have troubles with multi-threaded access. (Baruch 20010228)
                string childcommand(command); // copy
                string rest = split(command, childcommand, ' ');
                const int MAX_ARGV = 255;
                char *syscmd = 0; 
                char *argv[MAX_ARGV];
                int  index = 0;
-               bool more;
-               do {
+               bool more = true;
+               while (more) {
+                       childcommand = frontStrip(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;
+                       }
+                       
                        // reinit
                        more = !rest.empty();
                        if (more) 
                                rest = split(rest, childcommand, ' ');
-               } while (more);
+               }
                argv[index] = 0;
                // replace by command. Expand using PATH-environment-var.
                execvp(syscmd, argv);
@@ -176,13 +184,36 @@ pid_t Systemcalls::fork()
 // Reuse of instance
 
 int Systemcalls::startscript(Starttype how, string const & what, 
-                            Callbackfct cback)
+                             Callbackfct cback)
 {
        start   = how;
        command = what;
        cbk     = cback;
-       pid     = (pid_t) 0; // yet no child
+       pid     = static_cast<pid_t>(0); // yet no child
        retval  = 0;
+
+       if (how == SystemDontWait) {
+#ifndef __EMX__
+               command += " &";
+#else
+               // OS/2 cmd.exe has another use for '&'
+               // This is not NLS safe, but it's OK, I think.
+               string sh = OnlyFilename(GetEnvPath("EMXSHELL"));
+               if (sh.empty()) {
+                       // COMSPEC is set, unless user unsets 
+                       sh = OnlyFilename(GetEnvPath("COMSPEC"));
+                       if (sh.empty())
+                               sh = "cmd.exe";
+               }
+               sh = lowercase(sh);
+               if (contains(sh, "cmd.exe")
+                   || contains(sh, "4os2.exe"))
+                       command = "start /min/n " + command;
+               else
+                       command += " &";
+#endif
+       }
+
         return startscript();
 }
 
@@ -198,16 +229,16 @@ int Systemcalls::startscript(Starttype how, string const & what,
 int SimulateTimer;
 void back(string cmd, int retval)
 {
-       printf("Done: %s gave %d\n", cmd.c_str(), retval);
+       ::printf("Done: %s gave %d\n", cmd.c_str(), retval);
        SimulateTimer = 0;
 }
 
 
-int main(int, char**)
+int main(int, char **)
 {
        
        SystemcallsSingletoncontroller::Startcontroller starter; 
-       SystemcallsSingletoncontroller *contr=starter.GetController();
+       SystemcallsSingletoncontroller *contr= starter.GetController();
        
        Systemcalls one(Systemcalls::System, "ls -ltag", back);
        Systemcalls two(Systemcalls::Wait, "ls -ltag", back);