1

I need my command line application to wait for Ctrl-C in the main thread and then execute some deinitialization code and exit.

I tested this scenario with the following test program:

#include <unistd.h>
#include <signal.h>
#include <cstdlib>
#include <cstdio>
#include <cassert>

using namespace std;

void control_break_handler(int) { printf("\ncontrol_break_handler\n"); }

int main()
{
    printf("%s", "Before signal\n");

    int result = 0;

    struct sigaction sigact = {};
    result = sigemptyset(&sigact.sa_mask);
    assert(result == 0);
    sigact.sa_handler = &control_break_handler;
    sigact.sa_flags = 0;
    result = sigaction(SIGINT, &sigact, NULL);
    assert(result == 0);

    sigset_t set;
    result = sigemptyset(&set);
    assert(result == 0);
    result = sigaddset(&set, SIGINT);
    assert(result == 0);
    int sig;
    result = sigwait(&set, &sig);
    assert(result == 0);
    printf("\nsigwait returned %d, sig = %d\n", result, sig);

    sleep(10);

    return 0;
}

But it just prints

sigwait returned 0, sig = 2

after first Ctrl-C and the "control_break_handler" called only after the second Ctrl-C. How do I execute deinitialization code on first Ctrl-C? I use Ubuntu 13.04 x64.

EDIT: Ok, it seems I figured this out. I thrown away sigaction and added call to sigprocmask before sigwait. It seems to work just fine.

user10101
  • 1,704
  • 2
  • 20
  • 49
  • 1
    Don't use sigwait. You've registered your signal handler, it *will* be called before your application exits if the signal appears. – Joe Jul 31 '13 at 10:15
  • But then the main thread and hence the whole app immediately will exit. Do you mean I have to redesign the app to wait on worker threads not the SIGINT? – user10101 Jul 31 '13 at 10:18
  • Well, your main app somewhere has to spin doing its work?... – Joe Jul 31 '13 at 10:19
  • Suppose my app schedules some actions to be fired by timer every minute so it doesn't spin and just need to wait for SIGINT. – user10101 Jul 31 '13 at 10:26
  • Well you could do that. I think the point is that you have two ways of handling that signal. Synchronously with wait or asynchronously with a handler. Mostly people would assume that the signal is an unusual condition and handle it as an exception with a handler. – Joe Jul 31 '13 at 10:31
  • 2
    [Avoid using printf in a signal handler](http://stackoverflow.com/questions/16891019/how-to-avoid-using-printf-in-a-signal-handler/16891065#16891065) – Grijesh Chauhan Jul 31 '13 at 11:22
  • 1
    Additional to mask also set `sa.sa_flags = SA_RESTART;` To restart functions if interrupted by handler (as handlers called asynchronously) [Read this answer](http://stackoverflow.com/questions/17942034/simple-linux-signal-handling/17942230#17942230) – Grijesh Chauhan Jul 31 '13 at 11:25
  • 1
    @user835103 You welcome! ...using printf is immediate problem in your code. Remember always call safe function in signal handler and handler should small and simple. – Grijesh Chauhan Jul 31 '13 at 11:31

0 Answers0