Thread: [Cppcms-users] cppcms::service and system(..)
Brought to you by:
artyom-beilis
From: Christian G. <chr...@gm...> - 2012-07-18 11:04:19
|
Hi all, I would like to implement a Service class based on cppcms::service. I would like to trigger the rpc call via java script (works) and in the Service class I would like to use system() function to execute a bash script. If after executing/while executing the system function the cppcms apps hangs completely. My Service implements also a RPC call which does a reboot of the system - which works. Any idea what could went wrong? thanks --- Christian Gmeiner, MSc |
From: kpeo <sla...@ya...> - 2012-07-18 11:42:35
|
Hello, Fast answer: system() is not so thread-safe way for calling system scripts. E.g., you can use booster::aio::deadline_timer (async_wait method) or simple "old" pipe-method like this: # define MAX_BUFFER 1024 std::string vexec(std::string const &cmd) { char buf[MAX_BUFFER]; std::string out; FILE* pipe = popen(cmd.c_str(), "r" ); if (pipe == NULL ) { BOOSTER_LOG(debug,__FUNCTION__) << "invoking " << cmd << " is failed"; return ""; } while(1) { fgets(buf, MAX_BUFFER, pipe) != NULL ) { out.append(buf); } pclose(pipe); return out; } Shure, this realisation needs in implementing of timeout for waiting of answer. Regards, kpeo 18.07.2012, 15:03, "Christian Gmeiner" <chr...@gm...>: > Hi all, > > I would like to implement a Service class based on cppcms::service. I would like > to trigger the rpc call via java script (works) and in the Service > class I would like > to use system() function to execute a bash script. > > If after executing/while executing the system function the cppcms apps > hangs completely. > My Service implements also a RPC call which does a reboot of the > system - which works. > > Any idea what could went wrong? > > thanks > --- > Christian Gmeiner, MSc > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > Cppcms-users mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cppcms-users |
From: kpeo <sla...@ya...> - 2012-07-18 11:48:16
|
sorry, accidentally hit "send" ) # define MAX_BUFFER 1024 std::string vexec(std::string const &cmd, int timeout) { char buf[MAX_BUFFER]; std::string out; FILE* pipe = popen(cmd.c_str(), "r" ); if (pipe == NULL ) { BOOSTER_LOG(debug,__FUNCTION__) << "invoking " << cmd << " is failed"; return ""; } while(fgets(buf, MAX_BUFFER, pipe) != NULL) { out.append(buf); } pclose(pipe); return out; } 18.07.2012, 15:03, "Christian Gmeiner" <chr...@gm...>: > Hi all, > > I would like to implement a Service class based on cppcms::service. I would like > to trigger the rpc call via java script (works) and in the Service > class I would like > to use system() function to execute a bash script. > > If after executing/while executing the system function the cppcms apps > hangs completely. > My Service implements also a RPC call which does a reboot of the > system - which works. > > Any idea what could went wrong? > > thanks > --- > Christian Gmeiner, MSc > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > Cppcms-users mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cppcms-users |
From: kpeo <sla...@ya...> - 2012-07-18 12:12:14
|
Ugh, never write a letter and especially code online, sorry ) (if it possible - please remove last my message from maillist) "while" in function originally looks like this, but needs in timeout implementation: while(fgets(buf, MAX_BUFFER, pipe) != NULL) { out.append(buf); } See additionally: Application Lifetime: http://cppcms.com/wikipp/en/page/cppcms_1x_application_lifetime Thread Safety: http://cppcms.com/wikipp/en/page/thread_safety Async programming: http://cppcms.com/wikipp/en/page/cppcms_1x_aio Thread about background processes: http://comments.gmane.org/gmane.comp.lib.cppcms.user/1326 Regards, kpeo 18.07.2012, 15:03, "Christian Gmeiner" <chr...@gm...>: > Hi all, > > I would like to implement a Service class based on cppcms::service. I would like > to trigger the rpc call via java script (works) and in the Service > class I would like > to use system() function to execute a bash script. > > If after executing/while executing the system function the cppcms apps > hangs completely. > My Service implements also a RPC call which does a reboot of the > system - which works. > > Any idea what could went wrong? > > thanks > --- > Christian Gmeiner, MSc > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > Cppcms-users mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cppcms-users |
From: Artyom B. <art...@ya...> - 2012-07-19 07:56:56
|
Make sure you do not call system from asynchronous application - call it only from thread pool In general I don't see why shouldn't system work. I have some project that run latex from the application (even thou not using system but rather using fork+exec) Bottom line show the code. Artyom Beilis -------------- CppCMS - C++ Web Framework: http://cppcms.com/ CppDB - C++ SQL Connectivity: http://cppcms.com/sql/cppdb/ >________________________________ > From: Christian Gmeiner <chr...@gm...> >To: cpp...@li... >Sent: Wednesday, July 18, 2012 2:03 PM >Subject: [Cppcms-users] cppcms::service and system(..) > >Hi all, > >I would like to implement a Service class based on cppcms::service. I would like >to trigger the rpc call via java script (works) and in the Service >class I would like >to use system() function to execute a bash script. > >If after executing/while executing the system function the cppcms apps >hangs completely. >My Service implements also a RPC call which does a reboot of the >system - which works. > >Any idea what could went wrong? > >thanks >--- >Christian Gmeiner, MSc > >------------------------------------------------------------------------------ >Live Security Virtual Conference >Exclusive live event will cover all the ways today's security and >threat landscape has changed and how IT managers can respond. Discussions >will include endpoint security, mobile security and the latest in malware >threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ >_______________________________________________ >Cppcms-users mailing list >Cpp...@li... >https://lists.sourceforge.net/lists/listinfo/cppcms-users > > > |
From: Christian G. <chr...@gm...> - 2012-07-19 12:58:53
|
2012/7/19 Artyom Beilis <art...@ya...>: > Make sure you do not call system from asynchronous application - call it > only from thread pool > The asynchronous application (javascript RPC) get the call to execute a bash script via system(..). How can I trigger the calling from thread pool? thanks --- Christian Gmeiner, MSc |
From: Artyom B. <art...@ya...> - 2012-07-19 13:40:14
|
----- Original Message ----- > From: Christian Gmeiner <chr...@gm...> > To: Artyom Beilis <art...@ya...>; cpp...@li... > Cc: > Sent: Thursday, July 19, 2012 3:58 PM > Subject: Re: [Cppcms-users] cppcms::service and system(..) > > 2012/7/19 Artyom Beilis <art...@ya...>: >> Make sure you do not call system from asynchronous application - call it >> only from thread pool >> > > The asynchronous application (javascript RPC) get the call to execute > a bash script Asynchronous JavaScript or Asynchronously mounted CppCMS Application/RPC http://cppcms.com/wikipp/en/page/cppcms_1x_application_lifetime I mean if you mount an application asynchronously than you can't call system from there as all I/O would be blocked by system > via system(..). How can I trigger the calling from thread pool? See in cppcms::service::thread_pool and cppcms::thread_pool documentation Artyom Beilis -------------- CppCMS - C++ Web Framework: http://cppcms.com/ CppDB - C++ SQL Connectivity: http://cppcms.com/sql/cppdb/ > > thanks > --- > Christian Gmeiner, MSc > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > Cppcms-users mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cppcms-users > |
From: Christian G. <chr...@gm...> - 2012-09-22 20:16:15
|
Hi all, I have found some time and I am still working in this issue. The current state is the following: void Service::calibrate() { // valid session needed if (!session().is_set("user")) { BOOSTER_DEBUG("Service") << __func__ << ") not logged in"; return; } // only local host is allowed to do this if (request().remote_addr() != "127.0.0.1") { BOOSTER_DEBUG("Service") << __func__ << ") only on local host - called from " << request().remote_addr(); response().out() << "$.jGrowl(\"" << translate("Touch calibration only allowed on local host") << "\");" << "\n"; return; } response().out() << "$.jGrowl(\"" << translate("Starting calibration") << "...\");" << "\n"; BOOSTER_DEBUG("Service") << __func__ << ") doing action"; system("/opt/scripts/set-backlight.sh 0"); system("/opt/scripts/xcalibrate-touch.sh"); system("/opt/scripts/set-backlight.sh 100"); BOOSTER_DEBUG("Service") << __func__ << ") done"; } system("/opt/scripts/set-backlight.sh 0"); call works as expected but the whole web apps hangs at the next call: system("/opt/scripts/xcalibrate-touch.sh"); ----------------------------------------- #!/bin/bash # Invokes touch screen calibrator (x11) export DISPLAY=:0.0 BINARY=/opt/xinput_calibrator CALDATA=`$BINARY | grep 'Setting new calibration data:' | cut -d ":" -f 2 | tr -d ' ' | sed 's/,/ /g'` # if CALDATA is empty simply return if [ -z $CALDATA ]; then exit 0 fi # at the moment we store our axis_calib data in # the ID-Register. in some rare cases the # ID-Register is not accessable and we need a # fallback place to store our data. if [ -e /proc/idreg/axis_calib ]; then echo $CALDATA > /proc/idreg/axis_calib else echo $CALDATA > /home/vis/.axis_calib fi ----------------------------------------- xinput_calibrator can be found here https://github.com/tias/xinput_calibrator At the moment I am not sure whats wrong and how to debug it. maybe someone has an idea. --- Christian Gmeiner, MSc 2012/7/19 Artyom Beilis <art...@ya...>: > > > ----- Original Message ----- >> From: Christian Gmeiner <chr...@gm...> >> To: Artyom Beilis <art...@ya...>; cpp...@li... >> Cc: >> Sent: Thursday, July 19, 2012 3:58 PM >> Subject: Re: [Cppcms-users] cppcms::service and system(..) >> >> 2012/7/19 Artyom Beilis <art...@ya...>: >>> Make sure you do not call system from asynchronous application - call it >>> only from thread pool >>> >> >> The asynchronous application (javascript RPC) get the call to execute >> a bash script > > Asynchronous JavaScript or Asynchronously mounted CppCMS Application/RPC > > http://cppcms.com/wikipp/en/page/cppcms_1x_application_lifetime > > I mean if you mount an application asynchronously than you can't call system from there > as all I/O would be blocked by system > >> via system(..). How can I trigger the calling from thread pool? > > See in cppcms::service::thread_pool and cppcms::thread_pool documentation > > > > Artyom Beilis > > -------------- > CppCMS - C++ Web Framework: http://cppcms.com/ > CppDB - C++ SQL Connectivity: http://cppcms.com/sql/cppdb/ > > >> >> thanks >> --- >> Christian Gmeiner, MSc >> >> ------------------------------------------------------------------------------ >> Live Security Virtual Conference >> Exclusive live event will cover all the ways today's security and >> threat landscape has changed and how IT managers can respond. Discussions >> will include endpoint security, mobile security and the latest in malware >> threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ >> _______________________________________________ >> Cppcms-users mailing list >> Cpp...@li... >> https://lists.sourceforge.net/lists/listinfo/cppcms-users >> > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > Cppcms-users mailing list > Cpp...@li... > https://lists.sourceforge.net/lists/listinfo/cppcms-users |
From: Christian G. <chr...@gm...> - 2012-09-22 20:17:12
|
2012/9/22 Christian Gmeiner <chr...@gm...>: > Hi all, > > > I have found some time and I am still working in this issue. The > current state is the following: > > void Service::calibrate() > { > // valid session needed > if (!session().is_set("user")) > { > BOOSTER_DEBUG("Service") << __func__ << ") not logged in"; > return; > } > > // only local host is allowed to do this > if (request().remote_addr() != "127.0.0.1") > { > BOOSTER_DEBUG("Service") << __func__ << ") only on local host > - called from " << request().remote_addr(); > response().out() << "$.jGrowl(\"" << translate("Touch > calibration only allowed on local host") << "\");" << "\n"; > return; > } > > response().out() << "$.jGrowl(\"" << translate("Starting > calibration") << "...\");" << "\n"; > BOOSTER_DEBUG("Service") << __func__ << ") doing action"; > > system("/opt/scripts/set-backlight.sh 0"); > system("/opt/scripts/xcalibrate-touch.sh"); > system("/opt/scripts/set-backlight.sh 100"); > > BOOSTER_DEBUG("Service") << __func__ << ") done"; > } > > > system("/opt/scripts/set-backlight.sh 0"); call works as expected but > the whole web apps hangs > at the next call: > system("/opt/scripts/xcalibrate-touch.sh"); > > > ----------------------------------------- > #!/bin/bash > # Invokes touch screen calibrator (x11) > > export DISPLAY=:0.0 > BINARY=/opt/xinput_calibrator > > CALDATA=`$BINARY | grep 'Setting new calibration data:' | cut -d ":" > -f 2 | tr -d ' ' | sed 's/,/ /g'` > > # if CALDATA is empty simply return > if [ -z $CALDATA ]; then > exit 0 > fi > > # at the moment we store our axis_calib data in > # the ID-Register. in some rare cases the > # ID-Register is not accessable and we need a > # fallback place to store our data. > if [ -e /proc/idreg/axis_calib ]; then > echo $CALDATA > /proc/idreg/axis_calib > else > echo $CALDATA > /home/vis/.axis_calib > fi > ----------------------------------------- > > xinput_calibrator can be found here https://github.com/tias/xinput_calibrator > > > At the moment I am not sure whats wrong and how to debug it. maybe someone > has an idea. > Here is the syslog output: May 31 08:00:38 OT tssw: ajax_render: template: touch_display chromeless: 1 (base.cpp:79) May 31 08:00:38 OT tssw: i18n: current used locale en (base.cpp:88) May 31 08:00:38 OT tssw: cppcms_http: GET /keyboard.png (http_api.cpp:251) May 31 08:00:38 OT tssw: cppcms_http: GET /favicon.ico (http_api.cpp:251) May 31 08:00:41 OT tssw: cppcms_http: POST /tssw/rpc (http_api.cpp:251) May 31 08:00:41 OT tssw: cppcms: JSON-RPC Method call:calibrate (rpc_json.cpp:162) May 31 08:00:41 OT tssw: TsswService: calibrate) doing action (tssw.cpp:73) --- Christian Gmeiner, MSc |
From: Christian G. <chr...@gm...> - 2012-10-12 16:49:53
|
2012/9/22 Christian Gmeiner <chr...@gm...>: > 2012/9/22 Christian Gmeiner <chr...@gm...>: >> Hi all, >> >> >> I have found some time and I am still working in this issue. The >> current state is the following: >> >> void Service::calibrate() >> { >> // valid session needed >> if (!session().is_set("user")) >> { >> BOOSTER_DEBUG("Service") << __func__ << ") not logged in"; >> return; >> } >> >> // only local host is allowed to do this >> if (request().remote_addr() != "127.0.0.1") >> { >> BOOSTER_DEBUG("Service") << __func__ << ") only on local host >> - called from " << request().remote_addr(); >> response().out() << "$.jGrowl(\"" << translate("Touch >> calibration only allowed on local host") << "\");" << "\n"; >> return; >> } >> >> response().out() << "$.jGrowl(\"" << translate("Starting >> calibration") << "...\");" << "\n"; >> BOOSTER_DEBUG("Service") << __func__ << ") doing action"; >> >> system("/opt/scripts/set-backlight.sh 0"); >> system("/opt/scripts/xcalibrate-touch.sh"); >> system("/opt/scripts/set-backlight.sh 100"); >> >> BOOSTER_DEBUG("Service") << __func__ << ") done"; >> } >> >> >> system("/opt/scripts/set-backlight.sh 0"); call works as expected but >> the whole web apps hangs >> at the next call: >> system("/opt/scripts/xcalibrate-touch.sh"); >> >> >> ----------------------------------------- >> #!/bin/bash >> # Invokes touch screen calibrator (x11) >> >> export DISPLAY=:0.0 >> BINARY=/opt/xinput_calibrator >> >> CALDATA=`$BINARY | grep 'Setting new calibration data:' | cut -d ":" >> -f 2 | tr -d ' ' | sed 's/,/ /g'` >> >> # if CALDATA is empty simply return >> if [ -z $CALDATA ]; then >> exit 0 >> fi >> >> # at the moment we store our axis_calib data in >> # the ID-Register. in some rare cases the >> # ID-Register is not accessable and we need a >> # fallback place to store our data. >> if [ -e /proc/idreg/axis_calib ]; then >> echo $CALDATA > /proc/idreg/axis_calib >> else >> echo $CALDATA > /home/vis/.axis_calib >> fi >> ----------------------------------------- >> >> xinput_calibrator can be found here https://github.com/tias/xinput_calibrator >> >> >> At the moment I am not sure whats wrong and how to debug it. maybe someone >> has an idea. >> > > Here is the syslog output: > > May 31 08:00:38 OT tssw: ajax_render: template: touch_display > chromeless: 1 (base.cpp:79) > May 31 08:00:38 OT tssw: i18n: current used locale en (base.cpp:88) > May 31 08:00:38 OT tssw: cppcms_http: GET /keyboard.png (http_api.cpp:251) > May 31 08:00:38 OT tssw: cppcms_http: GET /favicon.ico (http_api.cpp:251) > May 31 08:00:41 OT tssw: cppcms_http: POST /tssw/rpc (http_api.cpp:251) > May 31 08:00:41 OT tssw: cppcms: JSON-RPC Method call:calibrate > (rpc_json.cpp:162) > May 31 08:00:41 OT tssw: TsswService: calibrate) doing action (tssw.cpp:73) I am quite sorry that I need to 'reopen' this thread but .... I do not get it working :( I want to run the following demo app from a cppcms app - its based on http://www.unix.com/programming/60469-runaway-sigalrm-signal-handler.html #include <stdio.h> #include <signal.h> #include <sys/time.h> #include <fcntl.h> #include <syslog.h> void on_alarm(int); /* handler for alarm */ void on_input(int); /* handler for keybd */ int set_timer( int which, long initial, long repeat ); volatile sig_atomic_t finished = 0; int main( int argc, char * argv[]) { int fd_flags; int k = 0; struct sigaction newhandler; sigset_t blocked; newhandler.sa_handler = on_input; /* handler function */ newhandler.sa_flags = 0; sigemptyset(&blocked); newhandler.sa_mask = blocked; if ( sigaction(SIGIO, &newhandler, NULL) == -1 ) perror("sigaction"); newhandler.sa_handler = on_alarm; /* handler function */ if ( sigaction(SIGALRM, &newhandler, NULL) == -1 ) perror("sigaction"); fcntl(0, F_SETOWN, getpid()); fd_flags = fcntl(0, F_GETFL); fcntl(0, F_SETFL, (fd_flags|O_ASYNC)); set_timer(ITIMER_REAL, 500, 500); while( !finished ) { pause(); printf("still in loop and finished = %d\n", finished); } return 0; } void on_input(int signum) { int c = getchar(); if ( c == 'q' ) finished = 1; } void on_alarm(int signum) { static int k = 0; syslog(LOG_INFO, "call number %d\n", k++); } int set_timer( int which, long initial, long repeat ) { struct itimerval itimer; long secs; // initialize initial delay secs = initial / 1000 ; itimer.it_value.tv_sec = secs; itimer.it_value.tv_usec = (initial - secs*1000 ) * 1000 ; // initialize repeat inveral secs = repeat / 1000 ; itimer.it_interval.tv_sec = secs; itimer.it_interval.tv_usec = (repeat - secs*1000 ) * 1000 ; return setitimer(which, &itimer, NULL); } It should print something like this to syslog Oct 12 00:01:59 OT xinput_calibrator: call number 0 Oct 12 00:02:00 OT xinput_calibrator: call number 1 Oct 12 00:02:00 OT xinput_calibrator: call number 2 Oct 12 00:02:01 OT xinput_calibrator: call number 3 Oct 12 00:02:01 OT xinput_calibrator: call number 4 Oct 12 00:02:02 OT xinput_calibrator: call number 5 Oct 12 00:02:02 OT xinput_calibrator: call number 6 Oct 12 00:02:03 OT xinput_calibrator: call number 7 If I run this within a json rpc request I via system("/opt/xinput_calibrator"); void Service::calibrate() { // valid session needed if (!session().is_set("user")) { BOOSTER_DEBUG("Service") << __func__ << ": not logged in"; return; } // only local host is allowed to do this if (request().remote_addr() != "127.0.0.1") { BOOSTER_DEBUG("Service") << __func__ << ": only on local host - called from " << request().remote_addr(); flash(translate("Touch calibration only allowed on local host")); } else { flash(translate("Starting calibration")); BOOSTER_DEBUG("Service") << __func__ << ": doing action"; #if 0 // here comes unix magic int master; pid_t pid = forkpty(&master, 0, 0, 0); if (pid == -1) { BOOSTER_ERROR("Service") << __func__ << ": pid = " << pid; return; } else if (pid == 0) { if (execl("/bin/su", "/bin/su", "vis", "-c", "/opt/scripts/xcalibrate-touch.sh", (char *)0) == -1 ) { BOOSTER_ERROR("Service") << __func__ << ": execlp " << errno; } BOOSTER_ERROR("Service") << __func__ << ": program exited"; return; } BOOSTER_DEBUG("Service") << __func__ << ": Child process: " << pid; BOOSTER_DEBUG("Service") << __func__ << ": done"; // TODO ... #endif //system("/bin/su vis -c /opt/scripts/xcalibrate-touch.sh"); system("/opt/xinput_calibrator"); } getFlashMessage(); BOOSTER_DEBUG("Service") << __func__ << ": done"; } It starts but nothing is in the system log :/ I think its a problem with the timer stuff.. has anybody an idea... would sponsor a (virtual) beer. root@OT:~# ps aux | grep xinput root 2070 0.0 0.0 1792 496 ? S 00:12 0:00 sh -c /opt/xinput_calibrator root 2071 0.0 0.0 1580 248 ? S 00:12 0:00 /opt/xinput_calibrator root 2075 0.0 0.1 3820 716 pts/2 S+ 00:12 0:00 grep xinput Other stuff like system("/sbin/reboot"); works... thanks --- Christian Gmeiner, MSc |