27 #include "../parser/iceparser.h"
28 #include "../parser/DependenciesGenerator.h"
35 #include <SimoxUtility/algorithm/string/string_tools.h>
41 #include <sys/types.h>
57 using namespace Parser;
63 char* name = (
char*)calloc(1024,
sizeof(
char));
66 sprintf(name,
"/proc/%d/cmdline", pid);
67 FILE* f = fopen(name,
"r");
71 size = fread(name,
sizeof(
char), 1024, f);
74 if (
'\n' == name[size - 1])
76 name[size - 1] =
'\0';
81 std::string result(name);
90 application->setStatusWriteBlock(
false);
95 scenario->setStatusWriteBlock(
false);
103 scenario->setStatusWriteBlock(
false);
105 std::vector<std::future<void>> futures;
107 std::vector<ApplicationInstancePtr> apps = *scenario->getApplications();
108 for (
auto it = apps.begin(); it != apps.end(); it++)
110 futures.push_back(startApplicationAsync(*it, statusManager, commandLineParameters, printOnly));
113 for (
auto future = futures.begin(); future != futures.end(); ++future)
124 app->setStatusWriteBlock(
false);
126 if (!app->getEnabled())
131 std::filesystem::path componentFolderPath = std::filesystem::path(ArmarXDataPath::GetCachePath()) /
"ComponentFiles";
133 if (!std::filesystem::exists(componentFolderPath))
135 if (!std::filesystem::create_directories(componentFolderPath))
137 std::cout <<
"Could not create Cache folder for ScenarioManagerPlugin at " << componentFolderPath.string() << std::endl;
142 std::filesystem::path dependenciesFilePath = componentFolderPath / std::filesystem::path(
"./" + app->getScenario()->getPackage()->getName() +
".dependencies.cfg");
144 if (!std::filesystem::exists(dependenciesFilePath))
150 if (!std::filesystem::exists(std::filesystem::path(app->getScenario()->getGlobalConfigPath()))
151 || !std::filesystem::exists(std::filesystem::path(app->getConfigPath()))
152 || !std::filesystem::exists(dependenciesFilePath))
154 std::cout <<
"Launching " << app->getName() <<
" in " << app->getScenario()->getPackage()->getName() <<
" without an needed cfg file";
156 if (!std::filesystem::exists(app->getExecutableAbsPath()))
158 std::cout <<
"\033[1;31m" <<
"Warning: Could not launch " << app->getName() <<
" in " << app->getScenario()->getPackage()->getName() <<
" because the executable is missing at " << app->getPathToExecutable() <<
"\033[0m" << std::endl;
161 args += app->getExecutableAbsPath();
162 args += std::string(
" --Ice.Config=").append(app->getScenario()->getGlobalConfigPath())
163 .append(
",").append(app->getConfigPath());
164 auto configDomain = app->getConfigDomain();
166 args += std::string(
" --" + configDomain +
".DependenciesConfig=").append(dependenciesFilePath.string());
167 args += std::string(
" --" + configDomain +
".LoggingGroup=").append(app->getScenario()->getName());
169 if (!commandLineParameters.empty())
171 Ice::StringSeq additional =
Split(commandLineParameters,
" ");
173 bool inString =
false;
174 std::string inStringChar;
175 std::string toPush =
"";
176 for (
auto command : additional)
178 if (!inString && command.find(
"\"") != std::string::npos)
183 else if (!inString && command.find(
"\'") != std::string::npos)
188 else if (inString && command.find(inStringChar) != std::string::npos)
192 args +=
" " + toPush;
199 toPush += command +
" ";
205 args +=
" " + command;
212 Ice::StringSeq additional =
Split(this->commandLineParameters,
" ");
213 for (
auto arg : additional)
220 using namespace boost::process::initializers;
221 #if defined(BOOST_POSIX_API)
223 signal(SIGCHLD, SIG_IGN);
228 for (
auto arg : args)
232 std::cout <<
" &" << std::endl << std::endl;
240 ARMARX_INFO <<
"Executing command `" << app->getExecutableAbsPath() <<
" "<< args;
254 if (application->getPid() < 0)
256 application->setPid(statusManager.
loadPid(application));
259 if (application->getPid() < 0)
265 std::string systemAppName = getSystemAppName(application);
270 if (systemAppName.empty())
272 application->setPid(-1);
273 statusManager.
savePid(application);
278 std::string runName = application->getExecutableName();
279 if (systemAppName.compare(runName) == 0)
281 return getStatus(application, statusManager);
286 ARMARX_INFO_S <<
"The Process name with Pid (" << application->getPid() <<
":" << systemAppName <<
") does not correspond with app name (" << application->getName() <<
"). Resetting Saved Pid.";
287 application->setPid(-1);
288 statusManager.
savePid(application);
296 std::string
status = getSystemAppStatus(application);
299 application->setPid(-1);
300 statusManager.
savePid(application);
314 if (namepluspath.empty())
320 std::string result = namepluspath.substr(namepluspath.rfind(
"/") + 1);
328 std::string processFilePath =
"/proc/";
329 processFilePath << application->getPid() <<
"/status";
330 std::ifstream t(processFilePath);
337 std::string stateLine;
339 while (std::getline(t, line))
347 if (stateLine.empty())
351 std::string result = stateLine.substr(stateLine.find(
':') + 1);
353 simox::alg::trim(result);
355 result = result.at(0);
357 if (result ==
"R" || result ==
"S")
361 else if (result ==
"D" || result ==
"Z")
365 else if (result ==
"T" || result ==
"X")
376 std::future<void> LinuxStarter::startApplicationAsync(
ApplicationInstancePtr application,
StatusManager statusManager,
const std::string& commandLineParameters,
bool printOnly)
378 if (application->getPid() != -1)
380 application->setStatusWriteBlock(
false);
381 return std::future<void>();
386 std::future<void> result = task.get_future();
387 std::thread t(std::move(task));