views:

69

answers:

3

I need to execute some commands via "/bin/sh" from a daemon. Some times these commands takes too long to execute, and I need to somehow interrupt them. The daemon is written in C++, and the commands are executed with std::system(). I need the stack cleaned up so that destructors are called when the thread dies. (Catching the event in a C++ exception-handler would be perfect).

The threads are created using boost:thread. Unfortunately, neither boost::thread::interrupt() or pthread_cancel() are useful in this case.

I can imagine several ways to do this, from writing my own version of system(), to finding the child's process-id and signal() it. But there must be a simpler way?

A: 

You can try to look at Boost.Process: http://stackoverflow.com/questions/1683665/where-is-boost-process I have been waiting for a long time for such a class.

If you are willing to use Qt, a nice portable solution is QProcess: http://doc.trolltech.com/4.1/qprocess.html

Of course, you can also make your own system-specific solution like Let_Me_Be suggests.

Anyway you'd probably have to get rid of the system() function call and replace it by a more powerful alternative.

Rémi
+2  A: 

Any command executed using the system command is executed in a new process. Unfortunately system halts the execution of the current process until the new process completes. If the sub process hangs the new process hangs as well.

The way to get round this is to use fork to create a new process and call one of the exec calls to execute the desired command. Your main process can then wait on the child process's Process Id (pid). The timeout can be achieve by generating a SIGALRM using the alarm call before the wait call.

If the sub process times out you can kill it using the kill command. Try first with SIGTERM, if that fails you can try again will SIGKILL, this will certainly kill the child process.

Some more information on fork and exec can be found here

doron