在基于 ncurses 的程序中拦截 SIGWINCH 后,无法识别按键

Lan*_*ich 2 c signals ncurses window-resize

我有一个基于 ncurses 的小程序,它执行基本的化学计算。它的主要功能是这样的:

int main() {   
  initscr();   
  cbreak();   
  nonl();   
  noecho(); 
  /* draws borderlines from position 0 to (COLS - 1) 
     for purely decorative purposes at the top and bottom
     of the screen */
  draw_GUI(); 
  keypress_loop();   
  endwin(); 
};
Run Code Online (Sandbox Code Playgroud)

keypress_loop()功能等待用户按下一个键,然后如果键是字母或数字,则在屏幕上打印该键的符号,如果键既不是字母也不是数字,则发出蜂鸣声。如果用户按下 F2 函数返回并且程序结束。

void  keypress_loop() 
{
   int key;
   while ((key = wgetch(stdscr)) != KEY_F(2))
      process_key(key); 
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都按预期工作。但随后我为 SIGWINCH 添加了一个信号处理程序,以确保在调整终端仿真器窗口的大小后正确重绘边界线。在我插入initscr()main()函数之前:

signal(SIGWINCH, handle_resizing);
Run Code Online (Sandbox Code Playgroud)

handle_resizing() 看起来像这样:

static void
handle_resizing(int signo) {
      endwin();
      initscr();   
      cbreak();   
      nonl();   
      noecho();
      draw_GUI();
}
Run Code Online (Sandbox Code Playgroud)

此 SIGWINCH 处理函数按预期重绘边界线。但问题是,当用户在调整大小后按下某个键时,程序会忽略该键。并且只有在用户按下一个键三次或更多次后,程序才开始识别该键,然后一切正常!如何使程序在调整大小后立即识别按键?

Tho*_*key 5

handle_resizing函数调用在信号处理程序中使用不安全的函数。该resizeterm手册有一节讨论这个。你的程序应该使用KEY_RESIZE从返回值getch