Re: [Cppcms-users] cppcms::service and system(..)
Brought to you by:
artyom-beilis
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 |