YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
localbroker.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
7#include <yarp/conf/string.h>
8
9#include <csignal>
10#include <cstring>
11
12#define RUN_TIMEOUT 10.0 //seconds
13#define STOP_TIMEOUT 15.0
14#define KILL_TIMEOUT 10.0
15#define CONNECTION_TIMEOUT 2.0
16
17#define WRITE_TO_PIPE 1
18#define READ_FROM_PIPE 0
19
20#if defined(_WIN32)
21 #include<Windows.h>
22 #define SIGKILL 9
23#else
24 #include <cstdlib>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <cerrno>
29 #include <unistd.h>
30 #include <cstring>
31
32 #define PIPE_TIMEOUT 0
33 #define PIPE_EVENT 1
34 #define PIPE_SIGNALED 2
35 #define C_MAXARGS 128 // max number of the command parameters
36#endif
37
38using namespace yarp::os;
39using namespace yarp::manager;
40
41
42#if defined(_WIN32)
44{
45public:
47 nWin = 0;
48 dwID = id;
49 }
50
52 int nWin;
53 DWORD dwID;
54};
55
57{
59 DWORD dwID;
61 if (dwID==params->dwID)
62 {
63 params->nWin++;
65 }
66 return TRUE ;
67}
68#if defined(_WIN64)
69volatile LONGLONG uniquePipeNumber = 0;
70#else
71volatile LONG uniquePipeNumber = 0;
72#endif
73
74/*
75* TODO: check deeply for asyn PIPE
76*/
82{
86 nSize = (nSize ==0) ? 100*8096: nSize;
87
88#if defined(_WIN64)
90#else
92#endif
93
95 "\\\\.\\Pipe\\RemoteExeAnon.%08x.%08x",
98 );
99
103 PIPE_TYPE_BYTE | PIPE_WAIT, //PIPE_NOWAIT,
104 1, // Number of pipes
105 nSize, // Out buffer size
106 nSize, // In buffer size
107 120 * 1000, // Timeout in ms
109 );
110
111 if (! ReadPipeHandle) {
112 return FALSE;
113 }
114
118 0, // No sharing
122 nullptr // Template file
123 );
124
126 {
130 return FALSE;
131 }
132
135 return( TRUE );
136}
137
138#endif
139
141{
142 bOnlyConnector = bInitialized = false;
143 ID = 0;
144 fd_stdout = nullptr;
146}
147
148
153
155{
156 if (Thread::isRunning()) {
157 Thread::stop();
158 }
159}
160
162{
163 /*
164 if(!NetworkBase::checkNetwork(5.0))
165 {
166 strError = "YARP network server is not up.";
167 return false;
168 }
169 */
170 bInitialized = true;
171 bOnlyConnector = true;
172 return true;
173}
174
175bool LocalBroker::init(const char* szcmd, const char* szparam,
176 const char* szhost, const char* szstdio,
177 const char* szworkdir, const char* szenv )
178{
179
180 strCmd.clear();
181 strParam.clear();
182 strHost.clear();
183 strStdio.clear();
184 strWorkdir.clear();
185 strTag.clear();
186 strEnv.clear();
187
188 if(!szcmd)
189 {
190 strError = "command is not specified.";
191 return false;
192 }
193 strCmd = szcmd;
194 if (szparam && strlen(szparam)) {
195 strParam = szparam;
196 }
197
198 if (szhost && strlen(szhost)) {
199 strHost = szhost;
200 }
201 if (szworkdir && strlen(szworkdir)) {
202 strWorkdir = szworkdir;
203 }
204
205 if(szstdio && strlen(szstdio))
206 {
207 if (szstdio[0] != '/') {
208 strStdio = std::string("/") + std::string(szstdio);
209 } else {
210 strStdio = szstdio;
211 }
212 }
213
214 if (szenv && strlen(szenv)) {
215 strEnv = szenv;
216 }
217
218 /*
219 OSTRINGSTREAM sstrID;
220 sstrID<<ID;
221 strTag = strHost + strCmd + sstrID.str();
222
223 if(!NetworkBase::checkNetwork(5.0))
224 {
225 strError = "YARP network server is not up.";
226 semParam.post();
227 return false;
228 }
229 */
230
231#if defined(_WIN32)
232 // do nothing
233 bInitialized = true;
234 return true;
235#else
236 /* avoiding zombie */
237 struct sigaction new_action;
238 new_action.sa_handler = SIG_IGN;
239 sigemptyset (&new_action.sa_mask);
240 new_action.sa_flags = 0;
241 sigaction (SIGCHLD, &new_action, nullptr);
242 bInitialized = true;
243 return true;
244#endif
245
246}
247
248
250{
251 if (!bInitialized) {
252 return false;
253 }
254 if (bOnlyConnector) {
255 return false;
256 }
257
258 if (running()) {
259 return true;
260 }
261
262 strError.clear();
263 ID = ExecuteCmd();
264 if (!ID) {
265 return false;
266 }
267
268 if(running())
269 {
270 return true;
271 }
272 return false;
273}
274
276{
277 if (!bInitialized) {
278 return true;
279 }
280 if (bOnlyConnector) {
281 return false;
282 }
283
284 strError.clear();
285#if defined(_WIN32)
286 stopCmd(ID);
287 stopStdout();
288#else
289 stopStdout();
290 stopCmd(ID);
291#endif
292
293 double base = SystemClock::nowSystem();
294 while(!timeout(base, STOP_TIMEOUT))
295 {
296 if (!running()) {
297 return true;
298 }
299 }
300
301 strError = "Timeout! cannot stop ";
302 strError += strCmd;
303 strError += " on ";
304 strError += strHost;
305 return false;
306}
307
309{
310 if (!bInitialized) {
311 return true;
312 }
313 if (bOnlyConnector) {
314 return false;
315 }
316
317 strError.clear();
318
319#if defined(_WIN32)
320 killCmd(ID);
321 stopStdout();
322#else
323 stopStdout();
324 stopCmd(ID);
325#endif
326
327 double base = SystemClock::nowSystem();
328 while(!timeout(base, KILL_TIMEOUT))
329 {
330 if (!running()) {
331 return true;
332 }
333 }
334
335 strError = "Timeout! cannot kill ";
336 strError += strCmd;
337 strError += " on ";
338 strError += strHost;
339 return false;
340}
341
342
344{
345 if (!bInitialized) {
346 return 0;
347 }
348 if (bOnlyConnector) {
349 return 0;
350 }
351 return (psCmd(ID))?1:0;
352}
353
354
358bool LocalBroker::connect(const std::string& from, const std::string& to, const std::string& carrier, bool persist)
359{
360
361 if(from.empty())
362 {
363 strError = "no source port is introduced.";
364 return false;
365 }
366
367 if (to.empty())
368 {
369 strError = "no destination port is introduced.";
370 return false;
371 }
372
373 if(!exists(from))
374 {
375 strError = from;
376 strError += " does not exist.";
377 return false;
378 }
379
380 if(!exists(to))
381 {
382 strError = to;
383 strError += " does not exist.";
384 return false;
385 }
386
387 if(!NetworkBase::connect(from, to, carrier) || !connected(from, to, carrier))
388 {
389 strError = "cannot connect ";
390 strError +=from;
391 strError += " to " + std::string(to);
392 return false;
393 }
394 return true;
395}
396
397bool LocalBroker::disconnect(const std::string& from, const std::string& to, const std::string& carrier)
398{
399
400 if (from.empty())
401 {
402 strError = "no source port is introduced.";
403 return false;
404 }
405
406 if (to.empty())
407 {
408 strError = "no destination port is introduced.";
409 return false;
410 }
411
412 if(!exists(from))
413 {
414 strError = from;
415 strError += " does not exist.";
416 return true;
417 }
418
419 if(!exists(to))
420 {
421 strError = to;
422 strError += " does not exist.";
423 return true;
424 }
425
426 if (!connected(from, to, carrier)) {
427 return true;
428 }
429
430 if(!NetworkBase::disconnect(from, to))
431 {
432 strError = "cannot disconnect ";
433 strError +=from;
434 strError += " from " + std::string(to);
435 return false;
436 }
437 return true;
438
439}
440
441bool LocalBroker::exists(const std::string& port)
442{
443 return NetworkBase::exists(port);
444}
445
446
447std::string LocalBroker::requestRpc(const std::string& szport, const std::string& request, double timeout)
448{
449 if (szport.empty() || request.empty()) {
450 return {};
451 }
452
453 if (!exists(szport)) {
454 return {};
455 }
456
457 // opening the port
458 yarp::os::Port port;
459 port.setTimeout((float)((timeout>0.0) ? timeout : CONNECTION_TIMEOUT));
460 if (!port.open("...")) {
461 return {};
462 }
463
464 ContactStyle style;
465 style.quiet = true;
466 style.timeout = (timeout>0.0) ? timeout : CONNECTION_TIMEOUT;
467 bool ret;
468 for(int i=0; i<10; i++) {
469 ret = NetworkBase::connect(port.getName(), szport, style);
470 if (ret) {
471 break;
472 }
474 }
475
476 if(!ret) {
477 port.close();
478 return {};
479 }
480
481 Bottle msg, response;
482 msg.fromString(request);
483 ret = port.write(msg, response);
485 if(!response.size() || !ret) {
486 port.close();
487 return {};
488 }
489
490 port.close();
491 return response.toString().c_str();
492}
493
494bool LocalBroker::connected(const std::string& from, const std::string& to, const std::string& carrier)
495{
496 if (!exists(from) || !exists(to)) {
497 return false;
498 }
499 return NetworkBase::isConnected(from, to);
500}
501
502
504{
505 return strError;
506}
507
509{
510 if (Thread::isRunning()) {
511 return true;
512 }
513 if(!running())
514 {
515 strError = "Module is not running";
516 return false;
517 }
518 return startStdout();
519}
520
522{
523 stopStdout();
524}
525
526
527bool LocalBroker::timeout(double base, double timeout)
528{
530 if ((SystemClock::nowSystem() - base) > timeout) {
531 return true;
532 }
533 return false;
534}
535
537{
538 return true;
539}
540
541
543{
544
545#if defined(_WIN32)
546 //windows implementation
548 CHAR buff[1024];
549 while(!Thread::isStopping())
550 {
552 buff, 1023, &dwRead, nullptr);
553 if(!bRet)
554 break;
555 buff[dwRead] = (CHAR)0;
556 if(eventSink && strlen(buff))
558 yarp::os::SystemClock::delaySystem(0.5); // this prevents event flooding
559 }
560#else
561 while(!Thread::isStopping())
562 {
563 if(waitPipeSignal(pipe_to_stdout[READ_FROM_PIPE]) == PIPE_EVENT)
564 {
565 if(fd_stdout)
566 {
567 std::string strmsg;
568 char buff[1024];
569 while (fgets(buff, 1024, fd_stdout)) {
570 strmsg += std::string(buff);
571 }
572 if (eventSink && strmsg.size()) {
574 }
575 yarp::os::SystemClock::delaySystem(0.5); // this prevents event flooding
576 }
577 }
578 }
579#endif
580}
581
582
586
587
589{
590 windowMode=m;
591}
592
593
594#if defined(_WIN32)
595
596std::string LocalBroker::lastError2String()
597{
598 int error=GetLastError();
599 char buff[1024];
600 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,nullptr,error,0,buff,1024,nullptr);
601 return std::string(buff);
602}
603
604bool LocalBroker::startStdout()
605{
607 return false;
609 return true;
610}
611
612void LocalBroker::stopStdout()
613{
614 Thread::stop();
615}
616
617int LocalBroker::ExecuteCmd()
618{
619 std::string strCmdLine = strCmd + std::string(" ") + strParam;
620
625 cmd_startup_info.cb = sizeof(STARTUPINFO);
626
627
628 std::string strDisplay=getDisplay();
629
631
632 //these come from xml
633 /*
634 // These are not supported until we find a way to send break signals to
635 // consoles that are not inherited
636 if (strDisplay=="--visible_na")
637 windowMode=WINDOW_VISIBLE;
638 if (strDisplay=="--hidden")
639 windowMode=WINDOW_HIDDEN;
640 */
641
642 // this is for "attach to stoud only"
643 if (windowMode==WINDOW_VISIBLE)
644 {
645 //this is common to all processes
647 cmd_startup_info.wShowWindow = SW_SHOWNA;
649 }
650 if (windowMode==WINDOW_HIDDEN)
651 {
652 // Setting up child process and pipe for stdout (useful for attaching stdout)
654 pipe_sec_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
655 pipe_sec_attr.bInheritHandle = TRUE;
656 pipe_sec_attr.lpSecurityDescriptor = nullptr;
659 &pipe_sec_attr, 0);
660
663
665
666 dwCreationFlags=CREATE_NEW_PROCESS_GROUP; //CREATE_NEW_CONSOLE|CREATE_NEW_PROCESS_GROUP,
667 }
668
669
670
671 /*
672 * setting environment variable for child process
673 */
674 TCHAR chNewEnv[32767];
675
676 // Get a pointer to the env block.
678
679 // copying parent env variables
682 while (*lpOld)
683 {
685 lpOld += lstrlen(lpOld) + 1;
686 lpNew += lstrlen(lpNew) + 1;
687 }
688
689 // adding new env variables
690 std::string cstrEnvName;
691 if(strEnv.size())
692 {
693 auto ss = yarp::conf::string::split(strEnv, ';');
694 for (const auto& s : ss) {
695 lstrcpy(lpNew, (LPTCH) s.c_str());
696 lpNew += lstrlen(lpNew) + 1;
697 }
698 }
699
700 // closing env block
701 *lpNew = (TCHAR)0;
702
703 bool bWorkdir=(strWorkdir.size()) ? true : false;
704 std::string strWorkdirOk = bWorkdir ? strWorkdir+std::string("\\") : "";
705
706 BOOL bSuccess=CreateProcess(nullptr, // command name
707 (char*)(strWorkdirOk+strCmdLine).c_str(), // command line
708 nullptr, // process security attributes
709 nullptr, // primary thread security attributes
710 TRUE, // handles are inherited
712 (LPVOID) chNewEnv, // use new environment
713 bWorkdir?strWorkdirOk.c_str():nullptr, // working directory
714 &cmd_startup_info, // STARTUPINFO pointer
715 &cmd_process_info); // receives PROCESS_INFORMATION
716
717 if (!bSuccess && bWorkdir)
718 {
719 bSuccess=CreateProcess(nullptr, // command name
720 (char*)(strCmdLine.c_str()), // command line
721 nullptr, // process security attributes
722 nullptr, // primary thread security attributes
723 TRUE, // handles are inherited
725 (LPVOID) chNewEnv, // use new environment
726 strWorkdirOk.c_str(), // working directory
727 &cmd_startup_info, // STARTUPINFO pointer
728 &cmd_process_info); // receives PROCESS_INFORMATION
729 }
730
731 // deleting old environment variable
733
736
737 if (!bSuccess)
738 {
739 strError = std::string("Can't execute command because ") + lastError2String();
740 return 0;
741 }
742
743 return cmd_process_info.dwProcessId;
744}
745
746bool LocalBroker::psCmd(int pid)
747{
749 if (hProc==nullptr)
750 return false;
751
752 DWORD status;
753 GetExitCodeProcess(hProc , &status);
755 return (status==STILL_ACTIVE);
756}
757
758bool LocalBroker::killCmd(int pid)
759{
761 if (hProc==nullptr)
762 return false;
763
766 return bRet ? true : false;
767}
768
769bool LocalBroker::stopCmd(int pid)
770{
772 if (hProc==nullptr)
773 return false;
774
775 LocalTerminateParams params(pid);
777
778 // I believe we do not need this. It is ignored by console applications created with CREATE_NEW_PROCESS_GROUP
780
781 //send BREAK_EVENT because we created the process with CREATE_NEW_PROCESS_GROUP
783
785 return true;
786}
787
788#else //for UNIX
789
790bool LocalBroker::psCmd(int pid)
791{
792 if (!pid) {
793 return false;
794 }
795 return !::kill(pid, 0);
796}
797
798
799bool LocalBroker::killCmd(int pid)
800{
801 if (!pid) {
802 return false;
803 }
804 return !::kill(pid, SIGKILL);
805}
806
807
808bool LocalBroker::stopCmd(int pid)
809{
810 if (!pid) {
811 return false;
812 }
813 return !::kill(pid, SIGTERM);
814}
815
816int LocalBroker::waitPipe(int pipe_fd)
817{
818 struct timeval timeout;
819 int rc;
820 fd_set fd;
821
822 timeout.tv_sec = 0;
823 timeout.tv_usec = 500000;
824
825 FD_ZERO(&fd);
826 FD_SET(pipe_fd, &fd);
827 rc = select(pipe_fd + 1, &fd, nullptr, nullptr, &timeout);
828 return rc;
829}
830
831
832int LocalBroker::waitPipeSignal(int pipe_fd)
833{
834 struct timespec timeout;
835 fd_set fd;
836
837 timeout.tv_sec = 2;
838 timeout.tv_nsec = 0;
839 FD_ZERO(&fd);
840 FD_SET(pipe_fd, &fd);
841
842 /*
843#if (_POSIX_C_SOURCE >= 200112L) || (_XOPEN_SOURCE >= 600)
844 struct sigaction new_action;
845 new_action.sa_handler = SIG_IGN;
846 sigemptyset (&new_action.sa_mask);
847 new_action.sa_flags = 0;
848 sigaction (SIGUSR1, &new_action, nullptr);
849 sigset_t sset, orgmask;
850 sigemptyset(&sset);
851 sigaddset(&sset, SIGUSR1);
852 pthread_sigmask(SIG_BLOCK, &sset, &orgmask);
853 if(pselect(pipe_fd + 1, &fd, nullptr, nullptr, &timeout, &orgmask))
854 return PIPE_EVENT;
855#endif
856*/
857 if (pselect(pipe_fd + 1, &fd, nullptr, nullptr, &timeout, nullptr)) {
858 return PIPE_EVENT;
859 }
860 return PIPE_TIMEOUT;
861}
862
863
864bool LocalBroker::startStdout()
865{
866 fd_stdout = fdopen(pipe_to_stdout[READ_FROM_PIPE], "r");
867 if(!fd_stdout)
868 {
869 strError = "cannot open pipe. " + std::string(strerror(errno));
870 //close(pipe_to_stdout[READ_FROM_PIPE]);
871 return false;
872 }
873
874 int oflags = fcntl(pipe_to_stdout[READ_FROM_PIPE], F_GETFL);
875 if(fcntl(pipe_to_stdout[READ_FROM_PIPE], F_SETFL, oflags|O_NONBLOCK) == -1)
876 {
877 strError = "cannot set flag on pipe: " + std::string(strerror(errno));
878 //close(pipe_to_stdout[READ_FROM_PIPE]);
879 return false;
880 }
882 return true;
883}
884
885void LocalBroker::stopStdout()
886{
887 Thread::stop();
888 if (fd_stdout) {
889 fclose(fd_stdout);
890 }
891 fd_stdout = nullptr;
892}
893
894
895
896int LocalBroker::ExecuteCmd()
897{
900 if (ret!=0)
901 {
902 strError = std::string("Can't create child pipe because") + std::string(strerror(errno));
903 return 0;
904 }
905
906 ret = pipe(pipe_to_stdout);
907 if (ret!=0)
908 {
909 strError = std::string("Can't create stdout pipe because") + std::string(strerror(errno));
910 return 0;
911 }
912
913 int pid_cmd = fork();
914
915 if(IS_INVALID(pid_cmd))
916 {
917 strError = std::string("Can't fork command because ") + std::string(strerror(errno));
918 return 0;
919 }
920
921 if (IS_NEW_PROCESS(pid_cmd)) // RUN COMMAND HERE
922 {
924 //int saved_stderr = dup(STDERR_FILENO);
925 dup2(pipe_to_stdout[WRITE_TO_PIPE], STDOUT_FILENO);
926 dup2(pipe_to_stdout[WRITE_TO_PIPE], STDERR_FILENO);
928 strError = std::string("Can't set flag on stdout: ") + std::string(strerror(errno));
929 return 0;
930 }
932 strError = std::string("Can't set flag on stderr: ") + std::string(strerror(errno));
933 return 0;
934 }
935
936 close(pipe_to_stdout[WRITE_TO_PIPE]);
937 close(pipe_to_stdout[READ_FROM_PIPE]);
938
939 strCmd = strCmd + std::string(" ") + strParam;
940 char *szcmd = new char[strCmd.size()+1];
941 strcpy(szcmd,strCmd.c_str());
942 int nargs = 0;
943 char **szarg = new char*[C_MAXARGS + 1];
945 szarg[nargs]=nullptr;
946 if(strEnv.size())
947 {
948 auto ss = yarp::conf::string::split(strEnv, ';');
949 for (const auto& s : ss) {
950 char* szenv = new char[s.size()+1];
951 strcpy(szenv, s.c_str());
952 putenv(szenv); // putenv doesn't make copy of the string
953 }
954 //delete szenv;
955 }
956
957 if(strWorkdir.size())
958 {
959 int ret = chdir(strWorkdir.c_str());
960 if (ret!=0)
961 {
962 strError = std::string("Can't set working directory because ") + std::string(strerror(errno));
964 fprintf(out_to_parent,"%s", strError.c_str());
968 delete [] szcmd;
969 delete [] szarg;
970 std::exit(ret);
971 }
972 }
973
974 char currWorkDirBuff[1024];
975 char *currWorkDir = getcwd(currWorkDirBuff,1024);
976
977 ret = 0;
978 if (currWorkDir)
979 {
980 char **cwd_szarg=new char*[nargs+1];
981 for (int i = 1; i < nargs; ++i) {
982 cwd_szarg[i] = szarg[i];
983 }
984 cwd_szarg[nargs]=nullptr;
985 cwd_szarg[0]=new char[strlen(currWorkDir)+strlen(szarg[0])+16];
986
988 strcat(cwd_szarg[0],"/");
989 strcat(cwd_szarg[0],szarg[0]);
991 delete [] cwd_szarg[0];
992 delete [] cwd_szarg;
993 }
994
995 if (ret==-1)
996 {
997 ret=execvp(szarg[0],szarg);
998 }
999
1000 if (ret==-1)
1001 {
1002 strError = std::string("Can't execute command because ") + std::string(strerror(errno));
1004 fprintf(out_to_parent,"%s", strError.c_str());
1007 }
1009 delete [] szcmd;
1010 delete [] szarg;
1011 ::exit(ret);
1012 }
1013
1014 if (IS_PARENT_OF(pid_cmd))
1015 {
1020 {
1021 strError = std::string("Can't set flag on pipe: ") + std::string(strerror(errno));
1023 return 0;
1024 }
1025
1026 std::string retError;
1028
1029 for (char buff[1024]; fgets(buff, 1024, in_from_child);) {
1030 retError += std::string(buff);
1031 }
1033
1034 if(retError.size())
1035 {
1036 strError = retError;
1038 return 0;
1039 }
1040
1041 close(pipe_to_stdout[WRITE_TO_PIPE]);
1043 return pid_cmd;
1044 }
1045
1046 return 0;
1047}
1048
1052void LocalBroker::splitLine(char *pLine, char **pArgs)
1053{
1054 char *pTmp = strchr(pLine, ' ');
1055
1056 if (pTmp) {
1057 *pTmp = '\0';
1058 pTmp++;
1059 while ((*pTmp) && (*pTmp == ' ')) {
1060 pTmp++;
1061 }
1062 if (*pTmp == '\0') {
1063 pTmp = nullptr;
1064 }
1065 }
1066 *pArgs = pTmp;
1067}
1068
1069
1070
1074void LocalBroker::parseArguments(char *io_pLine, int *o_pArgc, char **o_pArgv)
1075{
1076 char *pNext = io_pLine;
1077 size_t i;
1078 int j;
1079 int quoted = 0;
1080 size_t len = strlen(io_pLine);
1081
1082 // Protect spaces inside quotes, but lose the quotes
1083 for(i = 0; i < len; i++) {
1084 if ((!quoted) && ('"' == io_pLine[i])) {
1085 quoted = 1;
1086 io_pLine[i] = ' ';
1087 } else if ((quoted) && ('"' == io_pLine[i])) {
1088 quoted = 0;
1089 io_pLine[i] = ' ';
1090 } else if ((quoted) && (' ' == io_pLine[i])) {
1091 io_pLine[i] = '\1';
1092 }
1093 }
1094
1095 // init
1096 memset(o_pArgv, 0x00, sizeof(char*) * C_MAXARGS);
1097 *o_pArgc = 1;
1098 o_pArgv[0] = io_pLine;
1099
1100 while ((nullptr != pNext) && (*o_pArgc < C_MAXARGS)) {
1102 pNext = o_pArgv[*o_pArgc];
1103
1104 if (nullptr != o_pArgv[*o_pArgc]) {
1105 *o_pArgc += 1;
1106 }
1107 }
1108
1109 for(j = 0; j < *o_pArgc; j++) {
1110 len = strlen(o_pArgv[j]);
1111 for(i = 0; i < len; i++) {
1112 if('\1' == o_pArgv[j][i]) {
1113 o_pArgv[j][i] = ' ';
1114 }
1115 }
1116 }
1117}
1118#endif
bool ret
#define WRITE_TO_PIPE
Definition Run.cpp:60
#define READ_FROM_PIPE
Definition Run.cpp:59
void parseArguments(char *io_pLine, int *o_pArgc, char **o_pArgv)
Breaks up a line into multiple arguments.
Definition Run.cpp:2422
void splitLine(char *pLine, char **pArgs)
Split a line into separate words.
Definition Run.cpp:2402
#define C_MAXARGS
Definition Run.cpp:43
virtual void onBrokerStdout(const char *msg)
Definition broker.h:22
std::string strDisplay
Definition broker.h:67
BrokerEventSink * eventSink
Definition broker.h:65
std::string getDisplay() const
Definition broker.h:62
std::string requestRpc(const std::string &szport, const std::string &request, double timeout) override
void run() override
Main body of the new thread.
void setWindowMode(WindowMode m)
Define if the application will be visible or not.
bool exists(const std::string &port) override
bool threadInit() override
Initialization method.
bool disconnect(const std::string &from, const std::string &to, const std::string &carrier) override
void threadRelease() override
Release method.
bool connected(const std::string &from, const std::string &to, const std::string &carrier) override
std::string error() override
bool connect(const std::string &from, const std::string &to, const std::string &carrier, bool persist=false) override
connection broker
A simple collection of objects that can be described and transmitted in a portable way.
Definition Bottle.h:64
void fromString(const std::string &text)
Initializes bottle from a string.
Definition Bottle.cpp:204
size_type size() const
Gets the number of elements in the bottle.
Definition Bottle.cpp:251
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Definition Bottle.cpp:211
A mini-server for performing network communication in the background.
Preferences for how to communicate with a contact.
double timeout
Set a timeout for communication (in units of seconds, fractional seconds allowed).
bool quiet
Suppress all outputs and warnings.
virtual std::string getName() const
Get name of port.
static bool connect(const std::string &src, const std::string &dest, const std::string &carrier="", bool quiet=true)
Request that an output port connect to an input port.
Definition Network.cpp:682
static bool exists(const std::string &port, bool quiet=true, bool checkVer=true)
Check for a port to be ready and responsive.
Definition Network.cpp:746
static bool disconnect(const std::string &src, const std::string &dest, bool quiet)
Request that an output port disconnect from an input port.
Definition Network.cpp:700
static bool isConnected(const std::string &src, const std::string &dest, bool quiet)
Check if a connection with tcp carrier exists between two ports.
Definition Network.cpp:727
A mini-server for network communication.
Definition Port.h:46
bool write(const PortWriter &writer, const PortWriter *callback=nullptr) const override
Write an object to the port.
Definition Port.cpp:436
bool setTimeout(float timeout)
Set a timeout on network operations.
Definition Port.cpp:634
void close() override
Stop port activity.
Definition Port.cpp:363
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
Definition Port.cpp:79
static double nowSystem()
static void delaySystem(double seconds)
bool stop()
Stop the thread.
Definition Thread.cpp:81
bool isStopping()
Returns true if the thread is stopping (Thread::stop has been called).
Definition Thread.cpp:99
bool isRunning()
Returns true if the thread is running (Thread::start has been called successfully and the thread has ...
Definition Thread.cpp:105
bool start()
Start the new thread running.
Definition Thread.cpp:93
#define KILL_TIMEOUT
#define CONNECTION_TIMEOUT
#define PIPE_TIMEOUT
#define PIPE_EVENT
#define STOP_TIMEOUT
ContainerT split(const typename ContainerT::value_type &s, std::basic_regex< typename ContainerT::value_type::value_type > regex)
Utility to split a string by a separator, into a vector of strings.
Definition string.h:26
An interface to the operating system, including Port based communication.
char * getcwd(char *buf, size_t size)
Portable wrapper for the getcwd() function.
Definition Os.cpp:105
int fork()
Portable wrapper for the fork() function.