#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)
{
- start = how;
- command = what;
- cbk = cback;
- pid = static_cast<pid_t>(0);
- retval = 0;
- startscript();
+ startscript(how, what, cback);
}
Systemcalls::~Systemcalls() {
retval = 0;
switch (start) {
case System:
- retval = system(command.c_str());
+ case SystemDontWait:
+ retval = ::system(command.c_str());
callback();
break;
case Wait:
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
+ // dead within tolerance seconds
// CHECK Implement this using the timer of
// the singleton systemcontroller (Asger)
while (wait) {
pid_t waitrpid = waitpid(pid, &status, WUNTRACED);
if (waitrpid == -1) {
- lyxerr << "LyX: Error waiting for child:" << strerror(errno) << endl;
+ lyxerr << "LyX: Error waiting for child:"
+ << strerror(errno) << endl;
wait = false;
} else if (WIFEXITED(status)) {
// Child exited normally. Update return value.
pid_t Systemcalls::fork()
{
+ #ifndef __EMX__
pid_t cpid= ::fork();
if (cpid == 0) { // child
+ #endif
+ // 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.
+#ifndef __EMX__
execvp(syscmd, argv);
// If something goes wrong, we end up here:
- lyxerr << "LyX: execvp failed: " << strerror(errno) << endl;
+ lyxerr << "LyX: execvp failed: "
+ << strerror(errno) << endl;
} else if (cpid < 0) { // error
- lyxerr << "LyX: Could not fork: " << strerror(errno) << endl;
+#else
+ pid_t cpid = spawnvp(P_SESSION|P_DEFAULT|P_MINIMIZE|P_BACKGROUND, syscmd, argv);
+ if (cpid < 0) { // error
+#endif
+ lyxerr << "LyX: Could not fork: "
+ << strerror(errno) << endl;
} else { // parent
return cpid;
}
// Reuse of instance
int Systemcalls::startscript(Starttype how, string const & what,
- Callbackfct cback)
+ Callbackfct cback)
{
start = how;
command = what;
cbk = cback;
pid = static_cast<pid_t>(0); // yet no child
retval = 0;
+
+ if (how == SystemDontWait) {
+ if (os::shell() == os::UNIX) {
+ command += " &";
+ } else {
+ command = "start /min/n " + command;
+ }
+ }
+
return startscript();
}
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;
}