42 # if !defined(WIN32_LEAN_AND_MEAN)
43 # define WIN32_LEAN_AND_MEAN
47 # define C_MAXARGS 128 // the max number of command parameters. rational?
53 inline std::string lastError2String()
55 int error=GetLastError();
57 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
nullptr, error, 0, buff, 1024,
nullptr);
59 return std::string(buff);
63 #define READ_FROM_PIPE 0
64 #define WRITE_TO_PIPE 1
65 #define REDIRECT_TO(from, to) yarp::run::impl::dup2(to, from)
75 std::string yarp::run::Run::mPortName;
77 int yarp::run::Run::mProcCNT=0;
78 bool yarp::run::Run::mStresstest=
false;
79 bool yarp::run::Run::mLogged=
false;
80 std::string yarp::run::Run::mLoggerPort(
"/yarplogger");
92 sprintf(msg,
"SIGNAL %d", sig);
106 const char *at = txt.c_str();
109 for (
char ch : txt) {
111 result.
addString(std::string(at, len-slash_tweak));
117 slash_tweak = (ch==
slash && len>0)?1:0;
121 result.
addString(std::string(at, len-slash_tweak));
129 fp = fopen(fname,
"r");
146 if (config.
check(
"server"))
148 mLogged=config.
check(
"log");
154 if (botPortLogger.
size()>1)
160 mPortName=std::string(config.
find(
"server").
asString());
170 fprintf(stderr,
"ERROR: no yarp network found.\n");
177 if (config.
check(
"readwrite"))
180 std::string fPortName;
181 std::string lPortName;
183 if (config.
check(
"forward"))
193 #elif defined(__APPLE__)
196 struct sigaction new_action;
198 sigfillset(&new_action.sa_mask);
199 new_action.sa_flags=0;
201 sigaction(SIGTERM, &new_action,
nullptr);
202 sigaction(SIGHUP, &new_action,
nullptr);
205 yarp::os::impl::signal(SIGPIPE, SIG_IGN);
207 if (getppid()==1)
return 0;
209 yarp::os::impl::prctl(PR_SET_PDEATHSIG, SIGTERM);
211 struct sigaction new_action;
213 yarp::os::impl::sigfillset(&new_action.sa_mask);
214 new_action.sa_flags=0;
216 yarp::os::impl::sigaction(SIGTERM, &new_action,
nullptr);
217 yarp::os::impl::signal(SIGHUP, SIG_IGN);
219 yarp::os::impl::signal(SIGPIPE, SIG_IGN);
235 if (config.
check(
"write"))
244 struct sigaction new_action;
246 yarp::os::impl::sigfillset(&new_action.sa_mask);
247 new_action.sa_flags=0;
248 yarp::os::impl::sigaction(SIGTERM, &new_action,
nullptr);
250 yarp::os::impl::signal(SIGPIPE, SIG_IGN);
251 yarp::os::impl::signal(SIGHUP, SIG_IGN);
254 if (config.
check(
"log"))
276 if (config.
check(
"read"))
287 yarp::os::impl::signal(SIGHUP, SIG_IGN);
299 if (config.
check(
"stresstest"))
301 fprintf(stderr,
"Yarprun stress test started.\n");
304 int max_interval_ms=config.
find(
"stresstest").
asInt32();
309 config.
unput(
"stresstest");
313 bool isCommand=
false;
315 if (config.
check(
"cmd"))
322 unsigned int t=0, u=0;
326 char cmd_and_name[512];
330 std::random_device rd;
331 std::mt19937 mt(rd());
332 std::uniform_int_distribution<int> dist0maxint(0, max_interval_ms -1);
340 sprintf(tag,
"%s_%u", tag_zero.c_str(),
t++);
341 stresser.
put(
"as", tag);
345 sprintf(cmd_and_name,
"%s --name /%s", cmd.c_str(), tag);
346 stresser.
put(
"cmd", cmd_and_name);
351 std::uniform_int_distribution<int> dist07(0, 7);
352 if (isCommand && ++term_cycle>=4)
356 int r =
t - (dist07(mt));
358 for (
int i=u; i<r; ++i)
360 sprintf(tag,
"%s_%u", tag_zero.c_str(), i);
381 if (config.
check(
"help"))
389 if (config.
check(
"stdio")
390 || config.
check(
"cmd")
391 || config.
check(
"kill")
392 || config.
check(
"sigterm")
393 || config.
check(
"sigtermall")
394 || config.
check(
"exit")
395 || config.
check(
"isrunning")
396 || config.
check(
"ps")
397 || config.
check(
"env")
398 || config.
check(
"sysinfo")
399 || config.
check(
"which"))
415 for (
int r=0; r<RETRY; ++r)
419 if (!port.
open(
"..."))
432 RUNLOG(
"<<<port.write(msg, response)")
433 if (!port.
write(msg, response))
439 RUNLOG(
">>>port.write(msg, response)")
441 yarp::os::Network::disconnect(port.getName(), target);
444 fprintf(stderr, "RESPONSE:\n=========\n");
445 for (
size_t s=0; s<response.size(); ++s)
447 fprintf(stderr,
"%s\n", response.get(s).toString().c_str());
455 response.
addString(
"Cannot connect to remote server, aborting...\n");
456 for (
size_t s=0; s<response.
size(); ++s)
458 fprintf(stderr,
"%s\n", response.
get(s).
toString().c_str());
466 yarp::run::Run::mStresstest=
false;
468 if (yarp::run::Run::pServerPort)
471 yarp::run::Run::pServerPort =
nullptr;
482 int yarp::run::Run::server()
488 if (!port.
open(mPortName.c_str()))
490 yError() <<
"Yarprun failed to open port: " << mPortName.c_str();
501 yInfo() <<
"Yarprun successfully started on port: " << mPortName.c_str();
515 RUNLOG(
"<<<port.read(msg, true)")
516 if (!port.
read(msg, true)) break;
519 if (!pServerPort) break;
527 if (msg.check("stdio"))
529 std::string strOnPort=msg.find(
"on").asString();
530 std::string strStdioPort=msg.find(
"stdio").asString();
532 if (strOnPort==mPortName)
538 msg.addList()=botUUID;
540 if (mLogged || msg.check(
"log"))
543 std::string portName=
"/log";
544 portName+=mPortName+
"/";
545 std::string command = msg.findGroup(
"cmd").get(1).asString();
546 command = command.substr(0, command.find(
' '));
547 command = command.substr(command.find_last_of(
"\\/") + 1);
553 if (msg.check(
"log"))
557 if (botLogger.
size()>1)
570 msg.addList()=botFwd;
574 if (executeCmdAndStdio(msg, cmdResult)>0)
576 if (strStdioPort==mPortName)
579 userStdio(msg, stdioResult);
580 cmdResult.
append(stdioResult);
584 cmdResult.
append(sendMsg(msg, strStdioPort));
588 port.
reply(cmdResult);
593 userStdio(msg, stdioResult);
594 port.
reply(stdioResult);
601 if (msg.check(
"cmd"))
605 if (msg.check(
"log"))
609 if (botLogger.
size()>1)
611 std::string loggerName=botLogger.
get(1).
asString();
612 executeCmdStdout(msg, cmdResult, loggerName);
616 executeCmdStdout(msg, cmdResult, mLoggerPort);
621 executeCmdStdout(msg, cmdResult, mLoggerPort);
625 executeCmd(msg, cmdResult);
627 port.
reply(cmdResult);
631 if (msg.check(
"kill"))
633 std::string alias(msg.findGroup(
"kill").get(1).asString());
634 int sig=msg.findGroup(
"kill").get(2).asInt32();
636 result.
addString(mProcessVector.Signal(alias, sig)?
"kill OK":
"kill FAILED");
641 if (msg.check(
"sigterm"))
643 std::string alias(msg.find(
"sigterm").asString());
645 result.
addString(mProcessVector.Signal(alias, SIGTERM)?
"sigterm OK":
"sigterm FAILED");
650 if (msg.check(
"sigtermall"))
652 mProcessVector.Killall(SIGTERM);
662 result.
append(mProcessVector.PS());
667 if (msg.check(
"isrunning"))
669 std::string alias(msg.find(
"isrunning").asString());
671 result.
addString(mProcessVector.IsRunning(alias)?
"running":
"not running");
676 if (msg.check(
"killstdio"))
678 std::string alias(msg.find(
"killstdio").asString());
679 mStdioVector.Signal(alias, SIGTERM);
688 if (msg.check(
"sysinfo"))
695 if (msg.check(
"which"))
697 std::string fileName=msg.find(
"which").asString();
701 for (
int i=0; i<possiblePaths.
size(); ++i)
703 std::string guessString=possiblePaths.
get(i).
asString() +
704 std::string{
slash} + fileName;
705 const char* guess=guessString.c_str();
708 fileName=
"\"" + std::string(guess) +
"\"";
714 port.
reply(fileNameWriter);
718 if (msg.check(
"exit"))
729 Run::mStdioVector.Killall(SIGTERM);
731 Run::mProcessVector.Killall(SIGTERM);
737 #else // LINUX SERVER
740 void yarp::run::Run::cleanBeforeExec()
752 mProcessVector =
nullptr;
758 mStdioVector =
nullptr;
761 if (mBraveZombieHunter)
764 mBraveZombieHunter =
nullptr;
772 void yarp::run::Run::writeToPipe(
int fd, std::string str)
774 int len = str.length() + 1;
777 if (
ret !=
sizeof(len)) {
778 fprintf(stderr,
"Warning: could not write string length to pipe.\n");
782 fprintf(stderr,
"Warning: could not write string to pipe.\n");
786 int yarp::run::Run::readFromPipe(
int fd,
char* &data,
int& buffsize)
789 char* buff=(
char*)&len;
791 for (
int c=4, r=0; c>0; c-=r)
800 if (len<=0)
return 0;
805 data=
new char[buffsize=1024+(len/1024)*1024];
810 for (
int c=len, r=0; c>0; c-=r)
825 if (yarp::run::Run::mBraveZombieHunter)
831 int yarp::run::Run::server()
833 int pipe_server2manager[2];
834 int pipe_manager2server[2];
836 if (yarp::run::impl::pipe(pipe_server2manager))
838 fprintf(stderr,
"Can't open pipe because %s\n", strerror(errno));
844 if (yarp::run::impl::pipe(pipe_manager2server))
846 fprintf(stderr,
"Can't open pipe because %s\n", strerror(errno));
854 if (IS_INVALID(pid_process_manager))
863 fprintf(stderr,
"Can't fork process manager because %s\n", strerror(error));
869 if (IS_PARENT_OF(pid_process_manager))
871 yarp::os::impl::signal(SIGPIPE, SIG_IGN);
878 if (!port.
open(mPortName))
880 yError() <<
"Yarprun failed to open port: " << mPortName.c_str();
882 if (mPortName[0]!=
'/')
yError(
"Invalid port name '%s', it should start with '/'\n", mPortName.c_str());
893 yInfo() <<
"Yarprun successfully started on port: " << mPortName.c_str();
901 char *rsp_str=
new char[rsp_size];
907 RUNLOG(
"<<<port.read(msg, true)")
908 if (!port.
read(msg, true)) break;
911 if (!pServerPort) break;
913 if (msg.check("sysinfo"))
920 if (msg.check(
"which"))
922 std::string fileName=msg.find(
"which").asString();
926 for (
size_t i=0; i<possiblePaths.
size(); ++i)
929 const char* guess=guessString.c_str();
938 port.
reply(fileNameWriter);
942 if (msg.check(
"exit"))
944 pServerPort =
nullptr;
957 int nread=readFromPipe(pipe_manager2server[
READ_FROM_PIPE], rsp_str, rsp_size);
962 fprintf(stderr,
"ERROR: broken pipe between server and manager\n");
970 port.
reply(response);
984 if (IS_NEW_PROCESS(pid_process_manager))
986 yarp::os::impl::signal(SIGPIPE, SIG_IGN);
997 mBraveZombieHunter->
start();
1004 char *msg_str=
new char[msg_size];
1011 RUNLOG(
"<<<readFromPipe")
1012 if (readFromPipe(pipe_server2manager[
READ_FROM_PIPE], msg_str, msg_size)<=0) break;
1013 RUNLOG(">>>readFromPipe")
1018 msg.fromString(msg_str);
1021 if (msg.check("stdio"))
1026 if (strOnPort==mPortName)
1034 if (mLogged || msg.
check(
"log"))
1037 std::string portName=
"/log";
1038 portName+=mPortName+
"/";
1040 command = command.substr(0, command.find(
' '));
1041 command = command.substr(command.find_last_of(
"\\/") + 1);
1047 if (msg.
check(
"log"))
1051 if (botLogger.
size()>1)
1072 if (executeCmdAndStdio(msg, cmdResult)>0)
1074 if (strStdioPort==mPortName)
1077 userStdio(msg, stdioResult);
1078 cmdResult.
append(stdioResult);
1082 cmdResult.
append(sendMsg(msg, strStdioPort));
1093 userStdio(msg, stdioResult);
1103 if (msg.check("cmd"))
1107 if (msg.
check(
"log"))
1111 if (botLogger.
size()>1)
1113 std::string loggerName=botLogger.
get(1).
asString();
1114 executeCmdStdout(msg, cmdResult, loggerName);
1118 executeCmdStdout(msg, cmdResult, mLoggerPort);
1123 executeCmdStdout(msg, cmdResult, mLoggerPort);
1127 executeCmd(msg, cmdResult);
1136 if (msg.check("kill"))
1141 result.
addString(mProcessVector->Signal(alias, sig)?
"kill OK":
"kill FAILED");
1148 if (msg.check("sigterm"))
1152 result.
addString(mProcessVector->Signal(alias, SIGTERM)?
"sigterm OK":
"sigterm FAILED");
1159 if (msg.check("sigtermall"))
1161 mProcessVector->Killall(SIGTERM);
1171 if (msg.check("ps"))
1174 result.
append(mProcessVector->PS());
1181 if (msg.check("isrunning"))
1185 result.
addString(mProcessVector->IsRunning(alias)?
"running":
"not running");
1192 if (msg.check("killstdio"))
1195 mStdioVector->Signal(alias, SIGTERM);
1205 mStdioVector->Killall(SIGTERM);
1207 mProcessVector->Killall(SIGTERM);
1209 if (mBraveZombieHunter)
1211 mBraveZombieHunter->stop();
1212 delete mBraveZombieHunter;
1213 mBraveZombieHunter =
nullptr;
1216 delete mProcessVector;
1218 delete mStdioVector;
1240 if (config.
check(
"cmd") && config.
check(
"stdio"))
1246 Help(
"SYNTAX ERROR: missing remote stdio server\n");
1251 Help(
"SYNTAX ERROR: missing command\n");
1256 Help(
"SYNTAX ERROR: missing tag\n");
1261 Help(
"SYNTAX ERROR: missing remote server\n");
1267 printf(
"*********** %s ************\n", config.
toString().c_str());
1302 if (config.
check(
"cmd"))
1308 Help(
"SYNTAX ERROR: missing command\n");
1313 Help(
"SYNTAX ERROR: missing tag\n");
1318 Help(
"SYNTAX ERROR: missing remote server\n");
1354 if (config.
check(
"kill"))
1358 Help(
"SYNTAX ERROR: missing remote server\n");
1363 Help(
"SYNTAX ERROR: missing tag\n");
1368 Help(
"SYNTAX ERROR: missing signum\n");
1377 if (!response.
size())
1386 if (config.
check(
"sigterm"))
1390 Help(
"SYNTAX ERROR: missing tag");
1395 Help(
"SYNTAX ERROR: missing remote server\n");
1404 if (!response.
size())
1409 return response.
get(0).
asString()==
"sigterm OK"?0:2;
1413 if (config.
check(
"sigtermall"))
1417 Help(
"SYNTAX ERROR: missing remote server\n");
1426 if (!response.
size())
1434 if (config.
check(
"ps"))
1438 Help(
"SYNTAX ERROR: missing remote server\n");
1447 if (!response.
size())
1455 if (config.
check(
"isrunning"))
1459 Help(
"SYNTAX ERROR: missing remote server\n");
1465 Help(
"SYNTAX ERROR: missing tag\n");
1474 if (!response.
size())
1482 if (config.
check(
"sysinfo"))
1486 Help(
"SYNTAX ERROR: missing remote server\n");
1495 if (!port.
open(
"..."))
1497 fprintf(stderr,
"RESPONSE:\n=========\n");
1498 fprintf(stderr,
"Cannot open port, aborting...\n");
1507 fprintf(stderr,
"RESPONSE:\n=========\n");
1508 fprintf(stderr,
"Cannot connect to remote server, aborting...\n");
1516 RUNLOG(
"<<<port.write(msg, info)")
1518 RUNLOG(
">>>port.write(msg, info)")
1522 fprintf(stdout,
"RESPONSE:\n=========\n\n");
1526 fprintf(stdout,
"No response. (timeout)\n");
1531 fprintf(stdout,
"Platform name : %s\n", info.
platform.
name.c_str());
1533 fprintf(stdout,
"Platform release : %s\n", info.
platform.
release.c_str());
1535 fprintf(stdout,
"Platform kernel : %s\n\n", info.
platform.
kernel.c_str());
1537 fprintf(stdout,
"User Id : %d\n", info.
user.
userID);
1538 fprintf(stdout,
"User name : %s\n", info.
user.
userName.c_str());
1539 fprintf(stdout,
"User real name : %s\n", info.
user.
realName.c_str());
1540 fprintf(stdout,
"User home dir : %s\n\n", info.
user.
homeDir.c_str());
1543 fprintf(stdout,
"Cpu load 1 : %.2lf\n", info.
load.
cpuLoad1);
1544 fprintf(stdout,
"Cpu load 5 : %.2lf\n", info.
load.
cpuLoad5);
1545 fprintf(stdout,
"Cpu load 15 : %.2lf\n\n", info.
load.
cpuLoad15);
1553 fprintf(stdout,
"Processor model : %s\n", info.
processor.
model.c_str());
1556 fprintf(stdout,
"Processor vendor : %s\n", info.
processor.
vendor.c_str());
1570 if (config.
check(
"which"))
1574 Help(
"SYNTAX ERROR: missing remote server\n");
1584 if (!response.
size())
1591 if (config.
check(
"exit"))
1595 Help(
"SYNTAX ERROR: missing remote server\n");
1605 if (!response.
size())
1616 void yarp::run::Run::Help(
const char *msg)
1618 fprintf(stderr,
"%s", msg);
1619 fprintf(stderr,
"\nUSAGE:\n\n");
1620 fprintf(stderr,
"yarp run --server SERVERPORT\nrun a server on the local machine\n\n");
1621 fprintf(stderr,
"yarp run --on SERVERPORT --as TAG --cmd COMMAND [ARGLIST] [--workdir WORKDIR] [--env ENVIRONMENT]\nrun a command on SERVERPORT server\n\n");
1622 fprintf(stderr,
"yarp run --on SERVERPORT --as TAG --stdio STDIOSERVERPORT [--hold] [--geometry WxH+X+Y] --cmd COMMAND [ARGLIST] [--workdir WORKDIR] [--env ENVIRONMENT]\n");
1623 fprintf(stderr,
"run a command on SERVERPORT server sending I/O to STDIOSERVERPORT server\n\n");
1624 fprintf(stderr,
"yarp run --on SERVERPORT --kill TAG SIGNUM\nsend SIGNUM signal to TAG command\n\n");
1625 fprintf(stderr,
"yarp run --on SERVERPORT --sigterm TAG\nterminate TAG command\n\n");
1626 fprintf(stderr,
"yarp run --on SERVERPORT --sigtermall\nterminate all commands\n\n");
1627 fprintf(stderr,
"yarp run --on SERVERPORT --ps\nreport commands running on SERVERPORT\n\n");
1628 fprintf(stderr,
"yarp run --on SERVERPORT --isrunning TAG\nTAG command is running?\n\n");
1629 fprintf(stderr,
"yarp run --on SERVERPORT --sysinfo\nreport system information of SERVERPORT\n\n");
1630 fprintf(stderr,
"yarp run --on SERVERPORT --exit\nstop SERVERPORT server\n\n");
1646 std::string strStdioUUID=msg.
find(
"stdiouuid").
asString();
1650 SECURITY_ATTRIBUTES pipe_sec_attr;
1651 pipe_sec_attr.nLength=
sizeof(SECURITY_ATTRIBUTES);
1652 pipe_sec_attr.bInheritHandle=TRUE;
1653 pipe_sec_attr.lpSecurityDescriptor =
nullptr;
1654 HANDLE read_from_pipe_stdin_to_cmd, write_to_pipe_stdin_to_cmd;
1655 CreatePipe(&read_from_pipe_stdin_to_cmd, &write_to_pipe_stdin_to_cmd, &pipe_sec_attr, 0);
1656 HANDLE read_from_pipe_cmd_to_stdout, write_to_pipe_cmd_to_stdout;
1657 CreatePipe(&read_from_pipe_cmd_to_stdout, &write_to_pipe_cmd_to_stdout, &pipe_sec_attr, 0);
1660 PROCESS_INFORMATION stdout_process_info;
1661 ZeroMemory(&stdout_process_info,
sizeof(PROCESS_INFORMATION));
1662 STARTUPINFO stdout_startup_info;
1663 ZeroMemory(&stdout_startup_info,
sizeof(STARTUPINFO));
1665 stdout_startup_info.cb=
sizeof(STARTUPINFO);
1666 stdout_startup_info.hStdError=GetStdHandle(STD_ERROR_HANDLE);
1667 stdout_startup_info.hStdOutput=GetStdHandle(STD_OUTPUT_HANDLE);
1668 stdout_startup_info.hStdInput=read_from_pipe_cmd_to_stdout;
1669 stdout_startup_info.dwFlags|=STARTF_USESTDHANDLES;
1671 BOOL bSuccess=CreateProcess(
nullptr,
1672 (
char*)(std::string(
"yarprun --write ")+strStdioUUID).c_str(),
1676 CREATE_NEW_PROCESS_GROUP,
1679 &stdout_startup_info,
1680 &stdout_process_info);
1684 std::string strError=std::string(
"ABORTED: server=")+mPortName
1685 +std::string(
" alias=")+strAlias
1686 +std::string(
" cmd=stdout\n")
1687 +std::string(
"Can't execute stdout because ")+lastError2String()
1692 fprintf(stderr,
"%s", strError.c_str());
1695 CloseHandle(write_to_pipe_stdin_to_cmd);
1696 CloseHandle(read_from_pipe_stdin_to_cmd);
1697 CloseHandle(write_to_pipe_cmd_to_stdout);
1698 CloseHandle(read_from_pipe_cmd_to_stdout);
1705 PROCESS_INFORMATION stdin_process_info;
1706 ZeroMemory(&stdin_process_info,
sizeof(PROCESS_INFORMATION));
1707 STARTUPINFO stdin_startup_info;
1708 ZeroMemory(&stdin_startup_info,
sizeof(STARTUPINFO));
1710 stdin_startup_info.cb=
sizeof(STARTUPINFO);
1711 stdin_startup_info.hStdError=write_to_pipe_stdin_to_cmd;
1712 stdin_startup_info.hStdOutput=write_to_pipe_stdin_to_cmd;
1713 stdin_startup_info.hStdInput=GetStdHandle(STD_INPUT_HANDLE);
1714 stdin_startup_info.dwFlags|=STARTF_USESTDHANDLES;
1716 bSuccess=CreateProcess(
nullptr,
1717 (
char*)(std::string(
"yarprun --read ")+strStdioUUID).c_str(),
1721 CREATE_NEW_PROCESS_GROUP,
1724 &stdin_startup_info,
1725 &stdin_process_info);
1729 std::string strError=std::string(
"ABORTED: server=")+mPortName
1730 +std::string(
" alias=")+strAlias
1731 +std::string(
" cmd=stdin\n")
1732 +std::string(
"Can't execute stdin because ")+lastError2String()
1737 fprintf(stderr,
"%s", strError.c_str());
1739 TerminateProcess(stdout_process_info.hProcess,
YARPRUN_ERROR);
1741 CloseHandle(stdout_process_info.hProcess);
1743 CloseHandle(write_to_pipe_stdin_to_cmd);
1744 CloseHandle(read_from_pipe_stdin_to_cmd);
1745 CloseHandle(write_to_pipe_cmd_to_stdout);
1746 CloseHandle(read_from_pipe_cmd_to_stdout);
1753 PROCESS_INFORMATION cmd_process_info;
1754 ZeroMemory(&cmd_process_info,
sizeof(PROCESS_INFORMATION));
1755 STARTUPINFO cmd_startup_info;
1756 ZeroMemory(&cmd_startup_info,
sizeof(STARTUPINFO));
1758 cmd_startup_info.cb=
sizeof(STARTUPINFO);
1759 cmd_startup_info.hStdError=write_to_pipe_cmd_to_stdout;
1760 cmd_startup_info.hStdOutput=write_to_pipe_cmd_to_stdout;
1761 cmd_startup_info.hStdInput=read_from_pipe_stdin_to_cmd;
1762 cmd_startup_info.dwFlags|=STARTF_USESTDHANDLES;
1767 for (
int s=0; s<botCmd.
size(); ++s)
1769 strCmd+=botCmd.
get(s).
toString()+std::string(
" ");
1775 TCHAR chNewEnv[32767];
1778 LPTCH chOldEnv = GetEnvironmentStrings();
1781 LPTSTR lpOld = (LPTSTR) chOldEnv;
1782 LPTSTR lpNew = (LPTSTR) chNewEnv;
1785 lstrcpy(lpNew, lpOld);
1786 lpOld += lstrlen(lpOld) + 1;
1787 lpNew += lstrlen(lpNew) + 1;
1792 lstrcpy(lpNew, (LPTCH)
"YARP_IS_YARPRUN=1");
1793 lpNew += lstrlen(lpNew) + 1;
1797 lstrcpy(lpNew, (LPTCH)
"YARPRUN_IS_FORWARDING_LOG=1");
1798 lpNew += lstrlen(lpNew) + 1;
1801 std::string cstrEnvName;
1802 if (msg.
check(
"env"))
1805 for(
int i=0; i<ss.size(); i++) {
1806 lstrcpy(lpNew, (LPTCH) ss.get(i));
1807 lpNew += lstrlen(lpNew) + 1;
1814 bool bWorkdir=msg.
check(
"workdir");
1815 std::string strWorkdir=bWorkdir?msg.
find(
"workdir").
asString()+
"\\":
"";
1817 bSuccess=CreateProcess(
nullptr,
1818 (
char*)(strWorkdir+strCmd).c_str(),
1822 CREATE_NEW_PROCESS_GROUP,
1824 bWorkdir ? strWorkdir.c_str() :
nullptr,
1828 if (!bSuccess && bWorkdir)
1830 bSuccess=CreateProcess(
nullptr,
1831 (
char*)(strCmd.c_str()),
1835 CREATE_NEW_PROCESS_GROUP,
1843 FreeEnvironmentStrings(chOldEnv);
1850 std::string line1=std::string(
"ABORTED: server=")+mPortName
1851 +std::string(
" alias=")+strAlias
1852 +std::string(
" cmd=")+strCmd
1853 +std::string(
"pid=")+
int2String(cmd_process_info.dwProcessId)
1856 WriteFile(write_to_pipe_cmd_to_stdout, line1.c_str(), line1.length(), &nBytes, 0);
1858 std::string line2=std::string(
"Can't execute command because ")+lastError2String()+std::string(
"\n");
1859 WriteFile(write_to_pipe_cmd_to_stdout, line1.c_str(), line2.length(), &nBytes, 0);
1860 FlushFileBuffers(write_to_pipe_cmd_to_stdout);
1862 std::string out=line1+line2;
1864 fprintf(stderr,
"%s", out.c_str());
1867 CloseHandle(write_to_pipe_stdin_to_cmd);
1868 CloseHandle(read_from_pipe_stdin_to_cmd);
1869 CloseHandle(write_to_pipe_cmd_to_stdout);
1870 CloseHandle(read_from_pipe_cmd_to_stdout);
1872 TerminateProcess(stdout_process_info.hProcess,
YARPRUN_ERROR);
1874 CloseHandle(stdout_process_info.hProcess);
1876 TerminateProcess(stdin_process_info.hProcess,
YARPRUN_ERROR);
1878 CloseHandle(stdin_process_info.hProcess);
1883 FlushFileBuffers(write_to_pipe_cmd_to_stdout);
1889 cmd_process_info.dwProcessId,
1892 stdin_process_info.dwProcessId,
1893 stdout_process_info.dwProcessId,
1894 read_from_pipe_stdin_to_cmd,
1895 write_to_pipe_stdin_to_cmd,
1896 read_from_pipe_cmd_to_stdout,
1897 write_to_pipe_cmd_to_stdout,
1898 cmd_process_info.hProcess,
1902 if (msg.
check(
"env"))
1906 mProcessVector.Add(pInf);
1908 result.
addInt32(cmd_process_info.dwProcessId);
1909 std::string out=std::string(
"STARTED: server=")+mPortName
1910 +std::string(
" alias=")+strAlias
1911 +std::string(
" cmd=")+strCmd
1912 +std::string(
" pid=")+
int2String(cmd_process_info.dwProcessId)
1917 fprintf(stderr,
"%s", out.c_str());
1919 return cmd_process_info.dwProcessId;
1925 std::string portName=
"/log";
1926 portName+=mPortName+
"/";
1928 command = command.substr(0, command.find(
' '));
1929 command = command.substr(command.find_last_of(
"\\/") + 1);
1933 SECURITY_ATTRIBUTES pipe_sec_attr;
1934 pipe_sec_attr.nLength=
sizeof(SECURITY_ATTRIBUTES);
1935 pipe_sec_attr.bInheritHandle=TRUE;
1936 pipe_sec_attr.lpSecurityDescriptor =
nullptr;
1937 HANDLE read_from_pipe_cmd_to_stdout, write_to_pipe_cmd_to_stdout;
1938 CreatePipe(&read_from_pipe_cmd_to_stdout, &write_to_pipe_cmd_to_stdout, &pipe_sec_attr, 0);
1941 PROCESS_INFORMATION stdout_process_info;
1942 ZeroMemory(&stdout_process_info,
sizeof(PROCESS_INFORMATION));
1943 STARTUPINFO stdout_startup_info;
1944 ZeroMemory(&stdout_startup_info,
sizeof(STARTUPINFO));
1946 stdout_startup_info.cb=
sizeof(STARTUPINFO);
1947 stdout_startup_info.hStdError=GetStdHandle(STD_ERROR_HANDLE);
1948 stdout_startup_info.hStdOutput=GetStdHandle(STD_OUTPUT_HANDLE);
1949 stdout_startup_info.hStdInput=read_from_pipe_cmd_to_stdout;
1950 stdout_startup_info.dwFlags|=STARTF_USESTDHANDLES;
1952 BOOL bSuccess=CreateProcess(
nullptr,
1953 (
char*)(std::string(
"yarprun --log ")+loggerName+std::string(
" --write ")+portName).c_str(),
1957 CREATE_NEW_PROCESS_GROUP,
1960 &stdout_startup_info,
1961 &stdout_process_info);
1965 std::string strError=std::string(
"ABORTED: server=")+mPortName
1966 +std::string(
" alias=")+strAlias
1967 +std::string(
" cmd=stdout\n")
1968 +std::string(
"Can't execute stdout because ")+lastError2String()
1973 fprintf(stderr,
"%s", strError.c_str());
1976 CloseHandle(write_to_pipe_cmd_to_stdout);
1977 CloseHandle(read_from_pipe_cmd_to_stdout);
1984 PROCESS_INFORMATION cmd_process_info;
1985 ZeroMemory(&cmd_process_info,
sizeof(PROCESS_INFORMATION));
1986 STARTUPINFO cmd_startup_info;
1987 ZeroMemory(&cmd_startup_info,
sizeof(STARTUPINFO));
1989 cmd_startup_info.cb=
sizeof(STARTUPINFO);
1990 cmd_startup_info.hStdError=write_to_pipe_cmd_to_stdout;
1991 cmd_startup_info.hStdOutput=write_to_pipe_cmd_to_stdout;
1992 cmd_startup_info.hStdInput=GetStdHandle(STD_INPUT_HANDLE);
1993 cmd_startup_info.dwFlags|=STARTF_USESTDHANDLES;
1998 for (
int s=0; s<botCmd.
size(); ++s)
2000 strCmd+=botCmd.
get(s).
toString()+std::string(
" ");
2006 TCHAR chNewEnv[32767];
2009 LPTCH chOldEnv = GetEnvironmentStrings();
2012 LPTSTR lpOld = (LPTSTR) chOldEnv;
2013 LPTSTR lpNew = (LPTSTR) chNewEnv;
2016 lstrcpy(lpNew, lpOld);
2017 lpOld += lstrlen(lpOld) + 1;
2018 lpNew += lstrlen(lpNew) + 1;
2023 lstrcpy(lpNew, (LPTCH)
"YARP_IS_YARPRUN=1");
2024 lpNew += lstrlen(lpNew) + 1;
2028 lstrcpy(lpNew, (LPTCH)
"YARPRUN_IS_FORWARDING_LOG=1");
2029 lpNew += lstrlen(lpNew) + 1;
2032 std::string cstrEnvName;
2033 if (msg.
check(
"env"))
2035 lstrcpy(lpNew, (LPTCH) msg.
find(
"env").
asString().c_str());
2036 lpNew += lstrlen(lpNew) + 1;
2042 bool bWorkdir=msg.
check(
"workdir");
2043 std::string strWorkdir=bWorkdir?msg.
find(
"workdir").
asString()+
"\\":
"";
2045 bSuccess=CreateProcess(
nullptr,
2046 (
char*)(strWorkdir+strCmd).c_str(),
2050 CREATE_NEW_PROCESS_GROUP,
2052 bWorkdir?strWorkdir.c_str():
nullptr,
2056 if (!bSuccess && bWorkdir)
2058 bSuccess=CreateProcess(
nullptr,
2059 (
char*)(strCmd.c_str()),
2063 CREATE_NEW_PROCESS_GROUP,
2071 FreeEnvironmentStrings(chOldEnv);
2078 std::string line1=std::string(
"ABORTED: server=")+mPortName
2079 +std::string(
" alias=")+strAlias
2080 +std::string(
" cmd=")+strCmd
2081 +std::string(
"pid=")+
int2String(cmd_process_info.dwProcessId)
2084 WriteFile(write_to_pipe_cmd_to_stdout, line1.c_str(), line1.length(), &nBytes, 0);
2086 std::string line2=std::string(
"Can't execute command because ")+lastError2String()+std::string(
"\n");
2087 WriteFile(write_to_pipe_cmd_to_stdout, line1.c_str(), line2.length(), &nBytes, 0);
2088 FlushFileBuffers(write_to_pipe_cmd_to_stdout);
2090 std::string out=line1+line2;
2092 fprintf(stderr,
"%s", out.c_str());
2095 CloseHandle(write_to_pipe_cmd_to_stdout);
2096 CloseHandle(read_from_pipe_cmd_to_stdout);
2098 TerminateProcess(stdout_process_info.hProcess,
YARPRUN_ERROR);
2100 CloseHandle(stdout_process_info.hProcess);
2105 FlushFileBuffers(write_to_pipe_cmd_to_stdout);
2111 cmd_process_info.dwProcessId,
2112 stdout_process_info.dwProcessId,
2113 read_from_pipe_cmd_to_stdout,
2114 write_to_pipe_cmd_to_stdout,
2115 cmd_process_info.hProcess,
2122 if (msg.
check(
"env"))
2126 mProcessVector.Add(pInf);
2128 result.
addInt32(cmd_process_info.dwProcessId);
2129 std::string out=std::string(
"STARTED: server=")+mPortName
2130 +std::string(
" alias=")+strAlias
2131 +std::string(
" cmd=")+strCmd
2132 +std::string(
" pid=")+
int2String(cmd_process_info.dwProcessId)
2137 fprintf(stderr,
"%s", out.c_str());
2139 return cmd_process_info.dwProcessId;
2145 std::string strAlias=msg.
find(
"as").
asString().c_str();
2148 PROCESS_INFORMATION cmd_process_info;
2149 ZeroMemory(&cmd_process_info,
sizeof(PROCESS_INFORMATION));
2150 STARTUPINFO cmd_startup_info;
2151 ZeroMemory(&cmd_startup_info,
sizeof(STARTUPINFO));
2153 cmd_startup_info.cb=
sizeof(STARTUPINFO);
2158 for (
int s=0; s<botCmd.
size(); ++s)
2160 strCmd+=botCmd.
get(s).
toString()+std::string(
" ");
2166 TCHAR chNewEnv[32767];
2169 LPTCH chOldEnv = GetEnvironmentStrings();
2172 LPTSTR lpOld = (LPTSTR) chOldEnv;
2173 LPTSTR lpNew = (LPTSTR) chNewEnv;
2176 lstrcpy(lpNew, lpOld);
2177 lpOld += lstrlen(lpOld) + 1;
2178 lpNew += lstrlen(lpNew) + 1;
2183 lstrcpy(lpNew, (LPTCH)
"YARP_IS_YARPRUN=1");
2184 lpNew += lstrlen(lpNew) + 1;
2188 lstrcpy(lpNew, (LPTCH)
"YARPRUN_IS_FORWARDING_LOG=0");
2189 lpNew += lstrlen(lpNew) + 1;
2192 std::string cstrEnvName;
2193 if (msg.
check(
"env"))
2195 lstrcpy(lpNew, (LPTCH) msg.
find(
"env").
asString().c_str());
2196 lpNew += lstrlen(lpNew) + 1;
2202 bool bWorkdir=msg.
check(
"workdir");
2203 std::string strWorkdir=bWorkdir?msg.
find(
"workdir").
asString()+
"\\":
"";
2205 BOOL bSuccess=CreateProcess(
nullptr,
2206 (
char*)(strWorkdir+strCmd).c_str(),
2210 CREATE_NEW_PROCESS_GROUP,
2212 bWorkdir ? strWorkdir.c_str() :
nullptr,
2216 if (!bSuccess && bWorkdir)
2218 bSuccess=CreateProcess(
nullptr,
2219 (
char*)(strCmd.c_str()),
2223 CREATE_NEW_PROCESS_GROUP,
2231 FreeEnvironmentStrings(chOldEnv);
2237 std::string out=std::string(
"ABORTED: server=")+mPortName
2238 +std::string(
" alias=")+strAlias
2239 +std::string(
" cmd=")+strCmd
2240 +std::string(
" pid=")+
int2String(cmd_process_info.dwProcessId)
2241 +std::string(
"\nCan't execute command because ")+lastError2String()
2245 fprintf(stderr,
"%s", out.c_str());
2254 cmd_process_info.dwProcessId,
2255 cmd_process_info.hProcess,
2258 if (msg.
check(
"env"))
2261 mProcessVector.Add(pInf);
2263 result.
addInt32(cmd_process_info.dwProcessId);
2264 std::string out=std::string(
"STARTED: server=")+mPortName
2265 +std::string(
" alias=")+strAlias
2266 +std::string(
" cmd=")+strCmd
2267 +std::string(
" pid=")+
int2String(cmd_process_info.dwProcessId)
2270 fprintf(stderr,
"%s", out.c_str());
2272 return cmd_process_info.dwProcessId;
2278 PROCESS_INFORMATION stdio_process_info;
2279 ZeroMemory(&stdio_process_info,
sizeof(PROCESS_INFORMATION));
2281 STARTUPINFO stdio_startup_info;
2282 ZeroMemory(&stdio_startup_info,
sizeof(STARTUPINFO));
2283 stdio_startup_info.cb=
sizeof(STARTUPINFO);
2284 stdio_startup_info.wShowWindow=SW_SHOWNOACTIVATE;
2285 stdio_startup_info.dwFlags=STARTF_USESHOWWINDOW;
2289 std::string strCmd=std::string(
"yarprun --readwrite ")+strUUID;
2292 BOOL bSuccess=CreateProcess(
nullptr,
2293 (
char*)strCmd.c_str(),
2300 &stdio_startup_info,
2301 &stdio_process_info);
2309 stdio_process_info.dwProcessId,
2310 stdio_process_info.hProcess,
2313 out=std::string(
"STARTED: server=")+mPortName
2314 +std::string(
" alias=")+strAlias
2315 +std::string(
" cmd=stdio pid=")+
int2String(stdio_process_info.dwProcessId)
2322 out=std::string(
"ABORTED: server=")+mPortName
2323 +std::string(
" alias=")+strAlias
2324 +std::string(
" cmd=stdio\n")
2325 +std::string(
"Can't open stdio window because ")+lastError2String()
2330 result.
addInt32(stdio_process_info.dwProcessId);
2332 fprintf(stderr,
"%s", out.c_str());
2335 return stdio_process_info.dwProcessId;
2346 char *pTmp = strchr(pLine,
' ');
2351 while ((*pTmp) && (*pTmp ==
' ')) {
2354 if (*pTmp ==
'\0') {
2366 char *pNext = io_pLine;
2370 size_t len = strlen(io_pLine);
2373 for(i = 0; i < len; i++) {
2374 if ((!quoted) && (
'"' == io_pLine[i])) {
2377 }
else if ((quoted) && (
'"' == io_pLine[i])) {
2380 }
else if ((quoted) && (
' ' == io_pLine[i])) {
2386 memset(o_pArgv, 0x00,
sizeof(
char*) *
C_MAXARGS);
2388 o_pArgv[0] = io_pLine;
2390 while ((
nullptr != pNext) && (*o_pArgc <
C_MAXARGS)) {
2392 pNext = o_pArgv[*o_pArgc];
2394 if (
nullptr != o_pArgv[*o_pArgc]) {
2399 for(j = 0; j < *o_pArgc; j++) {
2400 len = strlen(o_pArgv[j]);
2401 for(i = 0; i < len; i++) {
2402 if (
'\1' == o_pArgv[j][i]) {
2403 o_pArgv[j][i] =
' ';
2409 void yarp::run::Run::CleanZombie(
int pid)
2411 bool bFound=mProcessVector && mProcessVector->CleanZombie(pid);
2413 if (!bFound)
if (mStdioVector) mStdioVector->CleanZombie(pid);
2423 std::string strStdioUUID=msg.
find(
"stdiouuid").
asString();
2425 int pipe_stdin_to_cmd[2];
2426 int ret_stdin_to_cmd=yarp::run::impl::pipe(pipe_stdin_to_cmd);
2428 int pipe_cmd_to_stdout[2];
2429 int ret_cmd_to_stdout=yarp::run::impl::pipe(pipe_cmd_to_stdout);
2431 int pipe_child_to_parent[2];
2432 int ret_child_to_parent=yarp::run::impl::pipe(pipe_child_to_parent);
2434 if (ret_child_to_parent!=0 || ret_cmd_to_stdout!=0 || ret_stdin_to_cmd!=0)
2438 std::string out=std::string(
"ABORTED: server=")+mPortName
2439 +std::string(
" alias=")+strAlias
2440 +std::string(
" cmd=stdout\n")
2441 +std::string(
"Can't create pipes ")+strerror(error)
2446 fprintf(stderr,
"%s", out.c_str());
2453 if (IS_INVALID(pid_stdout))
2464 std::string out=std::string(
"ABORTED: server=")+mPortName
2465 +std::string(
" alias=")+strAlias
2466 +std::string(
" cmd=stdout\n")
2467 +std::string(
"Can't fork stdout process because ")+strerror(error)
2472 fprintf(stderr,
"%s", out.c_str());
2477 if (IS_NEW_PROCESS(pid_stdout))
2493 int ret = yarp::run::impl::execlp(
"yarprun",
"yarprun",
"--write", strStdioUUID.c_str(),
static_cast<char*
>(
nullptr));
2501 std::string out=std::string(
"ABORTED: server=")+mPortName
2502 +std::string(
" alias=")+strAlias
2503 +std::string(
" cmd=stdout\n")
2504 +std::string(
"Can't execute stdout because ")+strerror(error)
2507 FILE* out_to_parent=fdopen(pipe_child_to_parent[
WRITE_TO_PIPE],
"w");
2508 fprintf(out_to_parent,
"%s", out.c_str());
2509 fflush(out_to_parent);
2510 fclose(out_to_parent);
2512 fprintf(stderr,
"%s", out.c_str());
2520 if (IS_PARENT_OF(pid_stdout))
2524 fprintf(stderr,
"STARTED: server=%s alias=%s cmd=stdout pid=%d\n", mPortName.c_str(), strAlias.c_str(), pid_stdout);
2528 if (IS_INVALID(pid_stdin))
2538 std::string out=std::string(
"ABORTED: server=")+mPortName
2539 +std::string(
" alias=")+strAlias
2540 +std::string(
" cmd=stdin\n")
2541 +std::string(
"Can't fork stdin process because ")+strerror(error)
2546 fprintf(stderr,
"%s", out.c_str());
2548 SIGNAL(pid_stdout, SIGTERM);
2549 fprintf(stderr,
"TERMINATING stdout (%d)\n", pid_stdout);
2554 if (IS_NEW_PROCESS(pid_stdin))
2570 int ret = yarp::run::impl::execlp(
"yarprun",
"yarprun",
"--read", strStdioUUID.c_str(),
static_cast<char*
>(
nullptr));
2578 std::string out=std::string(
"ABORTED: server=")+mPortName
2579 +std::string(
" alias=")+strAlias
2580 +std::string(
" cmd=stdin\n")
2581 +std::string(
"Can't execute stdin because ")+strerror(error)
2585 FILE* out_to_parent=fdopen(pipe_child_to_parent[
WRITE_TO_PIPE],
"w");
2586 fprintf(out_to_parent,
"%s", out.c_str());
2587 fflush(out_to_parent);
2588 fclose(out_to_parent);
2589 fprintf(stderr,
"%s", out.c_str());
2597 if (IS_PARENT_OF(pid_stdin))
2602 fprintf(stderr,
"STARTED: server=%s alias=%s cmd=stdin pid=%d\n", mPortName.c_str(), strAlias.c_str(), pid_stdin);
2606 if (IS_INVALID(pid_cmd))
2614 std::string out=std::string(
"ABORTED: server=")+mPortName
2615 +std::string(
" alias=")+strAlias
2616 +std::string(
" cmd=")+strCmd
2617 +std::string(
"\nCan't fork command process because ")+strerror(error)
2622 fprintf(stderr,
"%s", out.c_str());
2624 FILE* to_yarp_stdout=fdopen(pipe_cmd_to_stdout[
WRITE_TO_PIPE],
"w");
2625 fprintf(to_yarp_stdout,
"%s", out.c_str());
2626 fflush(to_yarp_stdout);
2627 fclose(to_yarp_stdout);
2629 SIGNAL(pid_stdout, SIGTERM);
2630 fprintf(stderr,
"TERMINATING stdout (%d)\n", pid_stdout);
2631 SIGNAL(pid_stdin, SIGTERM);
2632 fprintf(stderr,
"TERMINATING stdin (%d)\n", pid_stdin);
2639 if (IS_NEW_PROCESS(pid_cmd))
2643 char *cmd_str=
new char[strCmd.length()+1];
2644 strcpy(cmd_str, strCmd.c_str());
2652 char **arg_str =
new char*[
C_MAXARGS + 1];
2654 arg_str[nargs]=
nullptr;
2656 setvbuf(stdout,
nullptr, _IONBF, 0);
2670 if (msg.
check(
"env"))
2673 for(
int i=0; i<ss.size(); i++) {
2674 char* szenv =
new char[strlen(ss.get(i))+1];
2675 strcpy(szenv, ss.get(i));
2676 yarp::run::impl::putenv(szenv);
2681 if (msg.
check(
"workdir"))
2683 int ret = yarp::os::impl::chdir(msg.
find(
"workdir").
asString().c_str());
2689 std::string out=std::string(
"ABORTED: server=")+mPortName
2690 +std::string(
" alias=")+strAlias
2691 +std::string(
" cmd=")+strCmd
2692 +std::string(
"\nCan't execute command, cannot set working directory ")+strerror(error)
2695 FILE* out_to_parent=fdopen(pipe_child_to_parent[
WRITE_TO_PIPE],
"w");
2696 fprintf(out_to_parent,
"%s", out.c_str());
2697 fflush(out_to_parent);
2698 fclose(out_to_parent);
2699 fprintf(stderr,
"%s", out.c_str());
2707 char currWorkDirBuff[1024];
2712 char **cwd_arg_str=
new char*[nargs+1];
2713 for (
int i=1; i<nargs; ++i) cwd_arg_str[i]=arg_str[i];
2714 cwd_arg_str[nargs]=
nullptr;
2715 cwd_arg_str[0]=
new char[strlen(currWorkDir)+strlen(arg_str[0])+16];
2717 strcpy(cwd_arg_str[0], currWorkDir);
2718 strcat(cwd_arg_str[0],
"/");
2719 strcat(cwd_arg_str[0], arg_str[0]);
2726 ret = yarp::run::impl::execvp(cwd_arg_str[0], cwd_arg_str);
2728 delete [] cwd_arg_str[0];
2729 delete [] cwd_arg_str;
2739 ret = yarp::run::impl::execvp(arg_str[0], arg_str);
2751 std::string out=std::string(
"ABORTED: server=")+mPortName
2752 +std::string(
" alias=")+strAlias
2753 +std::string(
" cmd=")+strCmd
2754 +std::string(
"\nCan't execute command because ")+strerror(error)
2757 FILE* out_to_parent=fdopen(pipe_child_to_parent[
WRITE_TO_PIPE],
"w");
2758 fprintf(out_to_parent,
"%s", out.c_str());
2759 fflush(out_to_parent);
2760 fclose(out_to_parent);
2761 fprintf(stderr,
"%s", out.c_str());
2773 if (IS_PARENT_OF(pid_cmd))
2798 if (msg.
check(
"env"))
2803 mProcessVector->Add(pInf);
2807 FILE* in_from_child=fdopen(pipe_child_to_parent[
READ_FROM_PIPE],
"r");
2808 int flags=fcntl(pipe_child_to_parent[
READ_FROM_PIPE], F_GETFL, 0);
2809 fcntl(pipe_child_to_parent[
READ_FROM_PIPE], F_SETFL, flags|O_NONBLOCK);
2819 if (!fgets(buff, 1024, in_from_child) || ferror(in_from_child) || feof(in_from_child))
break;
2821 out+=std::string(buff);
2824 fclose(in_from_child);
2833 out=std::string(
"STARTED: server=")+mPortName
2834 +std::string(
" alias=")+strAlias
2835 +std::string(
" cmd=")+strCmd
2844 fprintf(stderr,
"%s", out.c_str());
2854 result.
addString(
"I should never reach this point!!!\n");
2864 std::string portName=
"/log";
2865 portName+=mPortName+
"/";
2867 std::string command = strCmd;
2868 command = command.substr(0, command.find(
' '));
2869 command = command.substr(command.find_last_of(
"\\/") + 1);
2875 int pipe_cmd_to_stdout[2];
2876 int ret_cmd_to_stdout=yarp::run::impl::pipe(pipe_cmd_to_stdout);
2878 int pipe_child_to_parent[2];
2879 int ret_child_to_parent=yarp::run::impl::pipe(pipe_child_to_parent);
2881 if (ret_child_to_parent!=0 || ret_cmd_to_stdout!=0)
2885 std::string out=std::string(
"ABORTED: server=")+mPortName
2886 +std::string(
" alias=")+strAlias
2887 +std::string(
" cmd=stdout\n")
2888 +std::string(
"Can't create pipes ")+strerror(error)
2893 fprintf(stderr,
"%s", out.c_str());
2900 if (IS_INVALID(pid_stdout))
2909 std::string out=std::string(
"ABORTED: server=")+mPortName
2910 +std::string(
" alias=")+strAlias
2911 +std::string(
" cmd=stdout\n")
2912 +std::string(
"Can't fork stdout process because ")+strerror(error)
2917 fprintf(stderr,
"%s", out.c_str());
2922 if (IS_NEW_PROCESS(pid_stdout))
2936 int ret = yarp::run::impl::execlp(
"yarprun",
"yarprun",
"--write", portName.c_str(),
"--log", loggerName.c_str(),
static_cast<char*
>(
nullptr));
2944 std::string out=std::string(
"ABORTED: server=")+mPortName
2945 +std::string(
" alias=")+strAlias
2946 +std::string(
" cmd=stdout\n")
2947 +std::string(
"Can't execute stdout because ")+strerror(error)
2950 FILE* out_to_parent=fdopen(pipe_child_to_parent[
WRITE_TO_PIPE],
"w");
2951 fprintf(out_to_parent,
"%s", out.c_str());
2952 fflush(out_to_parent);
2953 fclose(out_to_parent);
2955 fprintf(stderr,
"%s", out.c_str());
2963 if (IS_PARENT_OF(pid_stdout))
2967 fprintf(stderr,
"STARTED: server=%s alias=%s cmd=stdout pid=%d\n", mPortName.c_str(), strAlias.c_str(), pid_stdout);
2975 if (IS_INVALID(pid_cmd))
2982 std::string out=std::string(
"ABORTED: server=")+mPortName
2983 +std::string(
" alias=")+strAlias
2984 +std::string(
" cmd=")+strCmd
2985 +std::string(
"\nCan't fork command process because ")+strerror(error)
2990 fprintf(stderr,
"%s", out.c_str());
2992 FILE* to_yarp_stdout=fdopen(pipe_cmd_to_stdout[
WRITE_TO_PIPE],
"w");
2993 fprintf(to_yarp_stdout,
"%s", out.c_str());
2994 fflush(to_yarp_stdout);
2995 fclose(to_yarp_stdout);
2997 SIGNAL(pid_stdout, SIGTERM);
2998 fprintf(stderr,
"TERMINATING stdout (%d)\n", pid_stdout);
3004 if (IS_NEW_PROCESS(pid_cmd))
3008 char *cmd_str=
new char[strCmd.length()+1];
3009 strcpy(cmd_str, strCmd.c_str());
3017 char **arg_str =
new char*[
C_MAXARGS + 1];
3019 arg_str[nargs]=
nullptr;
3021 setvbuf(stdout,
nullptr, _IONBF, 0);
3034 if (msg.
check(
"env"))
3037 for(
int i=0; i<ss.size(); i++) {
3038 char* szenv =
new char[strlen(ss.get(i))+1];
3039 strcpy(szenv, ss.get(i));
3040 yarp::run::impl::putenv(szenv);
3045 if (msg.
check(
"workdir"))
3047 int ret = yarp::os::impl::chdir(msg.
find(
"workdir").
asString().c_str());
3053 std::string out=std::string(
"ABORTED: server=")+mPortName
3054 +std::string(
" alias=")+strAlias
3055 +std::string(
" cmd=")+strCmd
3056 +std::string(
"\nCan't execute command, cannot set working directory ")+strerror(error)
3059 FILE* out_to_parent=fdopen(pipe_child_to_parent[
WRITE_TO_PIPE],
"w");
3060 fprintf(out_to_parent,
"%s", out.c_str());
3061 fflush(out_to_parent);
3062 fclose(out_to_parent);
3063 fprintf(stderr,
"%s", out.c_str());
3071 char currWorkDirBuff[1024];
3072 char *currWorkDir=
getcwd(currWorkDirBuff, 1024);
3076 char **cwd_arg_str=
new char*[nargs+1];
3077 for (
int i=1; i<nargs; ++i) cwd_arg_str[i]=arg_str[i];
3078 cwd_arg_str[nargs]=
nullptr;
3079 cwd_arg_str[0]=
new char[strlen(currWorkDir)+strlen(arg_str[0])+16];
3081 strcpy(cwd_arg_str[0], currWorkDir);
3082 strcat(cwd_arg_str[0],
"/");
3083 strcat(cwd_arg_str[0], arg_str[0]);
3090 ret = yarp::run::impl::execvp(cwd_arg_str[0], cwd_arg_str);
3092 delete [] cwd_arg_str[0];
3093 delete [] cwd_arg_str;
3103 ret = yarp::run::impl::execvp(arg_str[0], arg_str);
3114 std::string out=std::string(
"ABORTED: server=")+mPortName
3115 +std::string(
" alias=")+strAlias
3116 +std::string(
" cmd=")+strCmd
3117 +std::string(
"\nCan't execute command because ")+strerror(error)
3120 FILE* out_to_parent=fdopen(pipe_child_to_parent[
WRITE_TO_PIPE],
"w");
3121 fprintf(out_to_parent,
"%s", out.c_str());
3122 fflush(out_to_parent);
3123 fclose(out_to_parent);
3124 fprintf(stderr,
"%s", out.c_str());
3136 if (IS_PARENT_OF(pid_cmd))
3155 if (msg.
check(
"env"))
3160 mProcessVector->Add(pInf);
3164 FILE* in_from_child=fdopen(pipe_child_to_parent[
READ_FROM_PIPE],
"r");
3165 int flags=fcntl(pipe_child_to_parent[
READ_FROM_PIPE], F_GETFL, 0);
3166 fcntl(pipe_child_to_parent[
READ_FROM_PIPE], F_SETFL, flags|O_NONBLOCK);
3176 if (!fgets(buff, 1024, in_from_child) || ferror(in_from_child) || feof(in_from_child))
break;
3178 out+=std::string(buff);
3181 fclose(in_from_child);
3190 out=std::string(
"STARTED: server=")+mPortName
3191 +std::string(
" alias=")+strAlias
3192 +std::string(
" cmd=")+strCmd
3200 fprintf(stderr,
"%s", out.c_str());
3210 result.
addString(
"I should never reach this point!!!\n");
3222 if (msg.
check(
"forward"))
3224 strCmd=std::string(
"/bin/bash -l -c \"yarprun --readwrite ")+strUUID
3229 strCmd=std::string(
"/bin/bash -l -c \"yarprun --readwrite ")+strUUID+
"\"";
3232 int pipe_child_to_parent[2];
3234 if (yarp::run::impl::pipe(pipe_child_to_parent))
3238 std::string out=std::string(
"ABORTED: server=")+mPortName
3239 +std::string(
" alias=")+strAlias
3240 +std::string(
" cmd=stdio\nCan't create pipe ")+strerror(error)
3246 fprintf(stderr,
"%s", out.c_str());
3253 for (
auto & i : command) {
3257 cmdcpy(command[c++],
"xterm");
3258 cmdcpy(command[c++], msg.
check(
"hold")?
"-hold":
"+hold");
3260 if (msg.
check(
"geometry"))
3262 cmdcpy(command[c++],
"-geometry");
3263 cmdcpy(command[c++], msg.
find(
"geometry").
asString().c_str());
3266 cmdcpy(command[c++],
"-title");
3267 cmdcpy(command[c++], strAlias.c_str());
3269 cmdcpy(command[c++],
"-e");
3270 cmdcpy(command[c++], strCmd.c_str());
3274 if (IS_INVALID(pid_cmd))
3278 std::string out=std::string(
"ABORTED: server=")+mPortName
3279 +std::string(
" alias=")+strAlias
3280 +std::string(
" cmd=stdio\nCan't fork stdout process because ")+strerror(error)
3286 fprintf(stderr,
"%s", out.c_str());
3296 if (IS_NEW_PROCESS(pid_cmd))
3311 int ret = yarp::run::impl::execvp(
"xterm", command);
3319 std::string out=std::string(
"ABORTED: server=")+mPortName
3320 +std::string(
" alias=")+strAlias
3321 +std::string(
" cmd=xterm\nCan't execute command because ")+strerror(error)
3324 FILE* out_to_parent=fdopen(pipe_child_to_parent[
WRITE_TO_PIPE],
"w");
3326 fprintf(out_to_parent,
"%s", out.c_str());
3327 fflush(out_to_parent);
3328 fclose(out_to_parent);
3330 fprintf(stderr,
"%s", out.c_str());
3338 if (IS_PARENT_OF(pid_cmd))
3342 mStdioVector->Add(
new YarpRunProcInfo(strAlias, mPortName, pid_cmd,
nullptr, msg.
check(
"hold")));
3350 FILE* in_from_child=fdopen(pipe_child_to_parent[
READ_FROM_PIPE],
"r");
3351 int flags=fcntl(pipe_child_to_parent[
READ_FROM_PIPE], F_GETFL, 0);
3352 fcntl(pipe_child_to_parent[
READ_FROM_PIPE], F_SETFL, flags|O_NONBLOCK);
3361 if (!fgets(buff, 1024, in_from_child) || ferror(in_from_child) || feof(in_from_child))
break;
3363 out+=std::string(buff);
3366 fclose(in_from_child);
3372 if (out.substr(0, 14)==
"xterm Xt error" || out.substr(0, 7)==
"ABORTED")
3378 out=std::string(
"STARTED: server=")+mPortName
3379 +std::string(
" alias=")+strAlias
3380 +std::string(
" cmd=xterm pid=")+
int2String(pid_cmd)
3385 fprintf(stderr,
"%s", out.c_str());
3406 int pipe_child_to_parent[2];
3407 int ret_pipe_child_to_parent=yarp::run::impl::pipe(pipe_child_to_parent);
3409 if (ret_pipe_child_to_parent!=0)
3413 std::string out=std::string(
"ABORTED: server=")+mPortName
3414 +std::string(
" alias=")+strAlias
3415 +std::string(
" cmd=stdio\nCan't create pipe ")+strerror(error)
3421 fprintf(stderr,
"%s", out.c_str());
3428 if (IS_INVALID(pid_cmd))
3432 std::string out=std::string(
"ABORTED: server=")+mPortName
3433 +std::string(
" alias=")+strAlias
3434 +std::string(
" cmd=")+strCmd
3435 +std::string(
"\nCan't fork command process because ")+strerror(error)
3440 fprintf(stderr,
"%s", out.c_str());
3445 if (IS_NEW_PROCESS(pid_cmd))
3447 int saved_stderr = yarp::run::impl::dup(STDERR_FILENO);
3448 int null_file=open(
"/dev/null", O_WRONLY);
3455 char *cmd_str=
new char[strCmd.length()+1];
3456 strcpy(cmd_str, strCmd.c_str());
3464 char **arg_str =
new char*[
C_MAXARGS + 1];
3466 arg_str[nargs]=
nullptr;
3476 if (msg.
check(
"env"))
3479 for(
int i=0; i<ss.size(); i++) {
3480 char* szenv =
new char[strlen(ss.get(i))+1];
3481 strcpy(szenv, ss.get(i));
3482 yarp::run::impl::putenv(szenv);
3486 if (msg.
check(
"workdir"))
3488 int ret = yarp::os::impl::chdir(msg.
find(
"workdir").
asString().c_str());
3494 std::string out=std::string(
"ABORTED: server=")+mPortName
3495 +std::string(
" alias=")+strAlias
3496 +std::string(
" cmd=")+strCmd
3497 +std::string(
"\nCan't execute command, cannot set working directory ")+strerror(error)
3500 FILE* out_to_parent=fdopen(pipe_child_to_parent[
WRITE_TO_PIPE],
"w");
3501 fprintf(out_to_parent,
"%s", out.c_str());
3502 fflush(out_to_parent);
3503 fclose(out_to_parent);
3506 fprintf(stderr,
"%s", out.c_str());
3512 char currWorkDirBuff[1024];
3513 char *currWorkDir=
getcwd(currWorkDirBuff, 1024);
3517 char **cwd_arg_str=
new char*[nargs+1];
3518 for (
int i=1; i<nargs; ++i) cwd_arg_str[i]=arg_str[i];
3519 cwd_arg_str[nargs]=
nullptr;
3520 cwd_arg_str[0]=
new char[strlen(currWorkDir)+strlen(arg_str[0])+16];
3523 strcpy(cwd_arg_str[0], currWorkDir);
3524 strcat(cwd_arg_str[0],
"/");
3525 strcat(cwd_arg_str[0], arg_str[0]);
3532 ret = yarp::run::impl::execvp(cwd_arg_str[0], cwd_arg_str);
3534 delete [] cwd_arg_str[0];
3535 delete [] cwd_arg_str;
3544 ret = yarp::run::impl::execvp(arg_str[0], arg_str);
3551 std::string out=std::string(
"ABORTED: server=")+mPortName
3552 +std::string(
" alias=")+strAlias
3553 +std::string(
" cmd=")+strCmd
3554 +std::string(
"\nCan't execute command because ")+strerror(error)
3557 FILE* out_to_parent=fdopen(pipe_child_to_parent[
WRITE_TO_PIPE],
"w");
3558 fprintf(out_to_parent,
"%s", out.c_str());
3559 fflush(out_to_parent);
3560 fclose(out_to_parent);
3562 if (saved_stderr >= 0)
3566 fprintf(stderr,
"%s", out.c_str());
3575 if (IS_PARENT_OF(pid_cmd))
3577 auto* pInf =
new YarpRunProcInfo(strAlias, mPortName, pid_cmd,
nullptr,
false);
3580 mProcessVector->Add(pInf);
3582 sprintf(pidstr,
"%d", pid_cmd);
3586 FILE* in_from_child=fdopen(pipe_child_to_parent[
READ_FROM_PIPE],
"r");
3587 int flags=fcntl(pipe_child_to_parent[
READ_FROM_PIPE], F_GETFL, 0);
3588 fcntl(pipe_child_to_parent[
READ_FROM_PIPE], F_SETFL, flags|O_NONBLOCK);
3598 if (!fgets(buff, 1024, in_from_child) || ferror(in_from_child) || feof(in_from_child))
break;
3600 out+=std::string(buff);
3603 fclose(in_from_child);
3612 out=std::string(
"STARTED: server=")+mPortName
3613 +std::string(
" alias=")+strAlias
3614 +std::string(
" cmd=")+strCmd
3619 fprintf(stderr,
"%s", out.c_str());
3650 std::string dest_srv=node;
3652 if (command.
check(
"stdio"))
3654 dest_srv=std::string(command.
find(
"stdio").
asString());
3661 if (command.
check(
"geometry"))
3669 if (command.
check(
"hold"))
3688 printf(
":: %s\n", msg.
toString().c_str());
3690 response=sendMsg(msg, dest_srv);
3693 sprintf(buff,
"%d", response.
get(0).
asInt32());
3694 keyv=std::string(buff);
3713 printf(
":: %s\n", msg.
toString().c_str());
3715 response=sendMsg(msg, node);
3733 printf(
":: %s\n", msg.
toString().c_str());
3735 response=sendMsg(msg, node);
3755 printf(
":: %s\n", msg.
toString().c_str());
3757 response=sendMsg(msg, node);
3776 printf(
":: %s\n", msg.
toString().c_str());
3778 response=sendMsg(msg, node);
3780 if (!response.
size())
return false;