#include <string>
#include <iostream>
#include <stdio.h>
+#include <errno.h>
// Project
#include <anna/xml/Compiler.hpp>
void cmdRunOnThread (TestStepCmd *step, const std::string &cmd) {
step->setThreadRunning(true);
int rc = system(cmd.c_str());
- if (rc != -1) rc >>= 8; // divide by 256
+ if (rc < 0 && errno == ECHILD) rc = 0; // ignore, it could happens
+ // I know one reason for this is that SICCHLD is set to SIG_IGN but this
+ // should not be the case here. SIGCHLD is explicity set to SIG_DFL
+ // using a sigaction before the call to system(). (Although it is
+ // normally set to SIG_IGN). There should not be any other threads
+ // messing about with SIGCHLD.
+
+ if (rc < 0) {
+ step->setErrorMsg(anna::functions::asString("errno = %d", errno));
+ //std::terminate;
+ }
+ else {
+ rc >>= 8; // divide by 256
+ }
+
step->setResultCode(rc);
step->complete();
// TODO: timeout the system call
result->createAttribute("Script", (a_script != "") ? a_script:"<no script>");
result->createAttribute("Parameters", (a_parameters != "") ? a_parameters:"<no parameters>");
result->createAttribute("CommandInProgress", a_threadRunning ? "yes":"no");
+ if (a_errorMsg != "") result->createAttribute("ErrorMessage", a_errorMsg);
if (!a_threadRunning && a_resultCode != -2) {
result->createAttribute("ResultCode", a_resultCode);
//if (a_output != "") result->createAttribute("Output", a_output);
bool a_threadRunning;
bool a_threadDeprecated;
int a_resultCode;
+ std::string a_errorMsg;
//std::string a_output;
public:
- TestStepCmd(TestCase *testCase) : TestStep(testCase), a_threadRunning(false), a_threadDeprecated(false), a_resultCode(-2)/*, a_output("")*/ { a_type = Type::Cmd; }
+ TestStepCmd(TestCase *testCase) : TestStep(testCase), a_threadRunning(false), a_threadDeprecated(false), a_resultCode(-2)/*, a_output("")*/, a_errorMsg("") { a_type = Type::Cmd; }
// setter & getters
void setThreadRunning(bool running) throw() { a_threadRunning = running; }
void setResultCode(int rc) throw() { a_resultCode = rc; }
int getResultCode() const throw() { return a_resultCode; }
+ void setErrorMsg(const std::string &em) throw() { a_errorMsg = em; }
+ const std::string &getErrorMsg() const throw() { return a_errorMsg; }
//void setOutput(const std::string &output) throw() { a_output = output; }
//const std::string &getOutput() const throw() { return a_output; }