Search code examples
c++terminalsignalsxterm

Program hangs after handling SIGWINCH


Just for fun I'm trying to write a library that does everything ncurses does, using iostreams and sending escape sequences directly to the terminal.

I'm trying to handle SIGWINCH to tell the library when the terminal is resized. The program responds normally until I resize the terminal, then it stops responding to input, even CTRL-C (although I'm not handling SIGINT, and have the terminal in "raw" mode using termios).

Here's some code snippets I've copied out of my code to show how I've set up the signal handler.

void handle_sigwinch(int sig)                                   
{                                                                               
  if(sig == SIGWINCH)    
  {
    // set a flag here
  }
}
void setup_signals()                                            
{       
  struct sigaction new_sig_action;                                            
  new_sig_action.sa_handler = handle_sigwinch;                
  sigemptyset (&new_sig_action.sa_mask);                                      
  new_sig_action.sa_flags = 0;                                                
  sigaction (SIGWINCH, NULL, &old_sig_action_);                               
  if (old_sig_action_.sa_handler != SIG_IGN)                                  
  {                                                                           
    sigaction (SIGWINCH, &new_sig_action, NULL);                              
  }                                                                           
}

int main()
{
  setup_signals();
  int ch;
  // exit if ctrl-c is pressed
  while((ch == cin.get()) != 3)
  {
     if(ch > 0)
       cout << (char)ch;
  }
}

I've tailored my code according to the example provided at https://www.gnu.org/software/libc/manual/html_node/Sigaction-Function-Example.html#Sigaction-Function-Example for setting up the signal handler.

Is there something I've failed to do after handling SIGWINCH that is causing my program to stop working?

Edit: I left out the code where I set up the terminal using cfmakeraw and tcsetattr, and prior to this I sent an escape sequence for putting xterm into the alternate screenbuffer mode.


Solution

  • Thanks to nos's comment, I found through the debugger that the program was running normally, but cin.get() wasn't receiving valid input anymore. So I changed my google search from "program hangs after signal handler" to "input stream broken after signal handler" and found this answer on StackOverflow, which allowed me to realize that the input stream was in an error state after the signal handler was called.

    I had placed a check before the input to ignore a character value of -1 (I must have been thinking of the Arduino library read statement when I did that, where -1 is an indicator that no input is available). So the program was basically ignoring errors on the input stream. (I edited my question's code to reflect that omission).

    I placed a cin.clear() statement immediately before the read in the loop, and now the program works as expected.