I'm trying to catch the Ctrl-C in application as demonstrated in the following MWE
#include <boost/asio/signal_set.hpp>
#include <iostream>
void handler( const boost::system::error_code& error , int signal_number )
{
std::cout << "handling signal " << signal_number << std::endl;
}
int main( int argc , char** argv )
{
boost::asio::io_service io_service;
// Construct a signal set registered for process termination.
boost::asio::signal_set signals(io_service, SIGINT );
// Start an asynchronous wait for one of the signals to occur.
signals.async_wait( handler );
char choice;
while( true )
{
std::cout << "Press a key: " << std::endl;
std::cin >> choice;
}
}
Unfortunately handler()
is not called when I press Ctrl+C. On the contrary the loop no longer waits for user input as shown below:
c:\tmp>CtrlC.exe
Press a key:
d
Press a key:
e
Press a key:
Press a key:
Press a key:
Press a key:
Press a key:
Press a key:
Press a key:
Press a key:
Press a key:
If it matters, I'm on Windows and I know that there is a Windows specific way to catch Ctrl+C but I'd like to use boost if possible for ease of porting.
boost ASIO in centered on the io_service
object, all the tasks you request (especially the async ones) are usually handled by the io_service
.
By doing:
// Start an asynchronous wait for one of the signals to occur.
signals.async_wait( handler );
You require the service to wait on the signals asynchronously and call your handler
when it happens.
The thing is, your io_service
is not running.
So if you want it to work correctly you need to start it:
#include <boost/asio/signal_set.hpp>
#include <iostream>
void handler( const boost::system::error_code& error , int signal_number )
{
std::cout << "handling signal " << signal_number << std::endl;
exit(1);
}
int main( int argc , char** argv )
{
boost::asio::io_service io_service;
// Construct a signal set registered for process termination.
boost::asio::signal_set signals(io_service, SIGINT );
// Start an asynchronous wait for one of the signals to occur.
signals.async_wait( handler );
io_service.run();
}
Then pressing Ctrl + C will do what you expect.
Note that the io_service
basically replaces your infinite loop, so anything you would have done inside of it should become tasks for the io_service
.
You need to let io_service
execute the handlers that has been passed to it. io_service
can don that only if you call run
or run_one
methods of it. You can make use of the run_one
method inside your while loop:
#include <boost/asio/signal_set.hpp>
#include <iostream>
#include <cstdlib>
#include <limits>
void handler( const boost::system::error_code& error , int signal_number )
{
// Not safe to use stream here...
std::cout << "handling signal " << signal_number << std::endl;
exit (1);
}
int main( int argc , char** argv )
{
boost::asio::io_service io_service;
// Construct a signal set registered for process termination.
boost::asio::signal_set signals(io_service, SIGINT );
// Start an asynchronous wait for one of the signals to occur.
signals.async_wait( handler );
char choice;
while( true )
{
std::cout << "Press a key: " << std::endl;
std::cin >> choice;
io_service.run_one();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With