0

I am writing a program in C using ncurses.I am trying to handle the CRTL C signal. In my code, this signal is being caught and dealt with but the program is not termination correctly. Could it be the way I am exiting from ncurses?

//handle SIGINT signal
void handle_signal(int signal){

   if(signal == SIGINT){

      clear();
      mvprintw(3,3,"A SIGNAL WAS ENCOUNTERED");
      refresh();
      sleep(1/2);
      exit(0);

    } //close if statement 

}//close handle_signal() function
CXB
  • 241
  • 5
  • 14
  • `sleep(1/2)`? Those are two integers so the result of that division will also be an integer. So this is the same as calling `sleep(0)`. Is that what you wanted? – SiggiSv May 20 '17 at 10:43
  • I did that only for testing to see the message printed.. It does not solve anything :( – CXB May 20 '17 at 10:48

2 Answers2

1

Without further research: I'd be VERY surprised if curses functions were actually signal safe. It's generally best practice to keep your signal handlers minmal, ideally just setting a flag. So, you should solve your problem like this:

static volatile sig_atomic_t interrupted = 0;

in your signal handler:

    if (signal == SIGINT)
    {
        interrupted = 1;
    }

somewhere in your main loop:

    if (interrupted)
    {
        clear();
        mvprintw(3,3,"A SIGNAL WAS ENCOUNTERED");
        refresh();
        sleep(1);
        endwin();
        exit(0);
    }

Note your code didn't call endwin() anywhere, this is required for restoring the terminal to normal.

1

As noted in the initscr manual page, ncurses installs a handler for SIGINT

The handler attempts to cleanup the screen on exit. Although it usually works as expected, there are limitations:

If you setup your handler before initscr (or newterm), it will not be called. If you setup the handler after, you'd have to take into account the various limitations of what functions you can safely call in a signal handler.

ncurses' handling of SIGINT takes into account the fact that some of the functions it would normally use are not safe, and it uses a different strategy when it has receive a signal (which is perhaps not 100% reliable, but an improvement).

Your signal handler does not take any of that into account, and for example ncurses could call malloc to handle some extra output-buffering needed, and "not work", since malloc is not a safe function to use.

Further reading:

Community
  • 1
  • 1
Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105