Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle a ctrl-break signal in a command line interface

Before I begin, I want to clarify that this is not a command-line tool, but an application that accepts commands through it's own command-line interface.

Edit: I must apologize about my explanation from before, apparently I didn't do a very good job at explaining it. One more time...

I am building a command-line interface application that accepts commands from a user. I have a signal handler setup to catch the signals, which then sets a flag that I need to terminate the application. The problem I'm having is all of the console functions I can find are blocking, which means that I can't detect that I need to exit from my console processing loop until the user presses a key (or enter, depending on the function).

Is there some standard way I can do either non-block console interaction, or is there an elegant way to structure the program so that if I just terminate from the signal thread, that everything will be handled and released properly (please don't mis-understand this, I know how this could be done using locking and releasing the resources from the signaling thread, but this could get messy, so I'd rather avoid it)

Hopefully that explanation makes more sense...

like image 496
Miquella Avatar asked Oct 08 '08 05:10

Miquella


2 Answers

OK - this is working for me on Windows & is portable - notice the #ifdef SIGBREAK - this isn't a standard signal.

#include <csignal>
#include <iostream>
#include <ostream>
#include <string>
using namespace std;

namespace
{
    volatile sig_atomic_t quit;

    void signal_handler(int sig)
    {
        signal(sig, signal_handler);
        quit = 1;
    }
}

int main()
{
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
#ifdef SIGBREAK
    signal(SIGBREAK, signal_handler);
#endif
    /* etc */

    while (!quit)
    {
        string s;
        cin >> s;
        cout << s << endl;
    }
    cout << "quit = " << quit << endl;
}
like image 95
fizzer Avatar answered Oct 10 '22 13:10

fizzer


On *nix, you can use the signal function to register a signal handler:


#include <signal.h>

void signal_handler(int sig)
{
  // Handle the signal
}

int main(void)
{
  // Register the signal handler for the SIGINT signal (Ctrl+C)
  signal(SIGINT, signal_handler);
  ...
}

Now, whenever someone hits Ctrl+C, your signal handler will be called.

like image 30
Adam Rosenfield Avatar answered Oct 10 '22 14:10

Adam Rosenfield