csigintpdcurses

How to handling SIGINT (Ctrl+C) while using PDCurses in Windows


I am using PDCurses to write console app in Windows. I want the app to terminate when I press Ctrl+C.

My minimal reproducible code is as below. If I comment out initscr() and endwin(), the app will terminal after receive SIGINT and print "End" in the console. However, it does not work with the two lines, and it will fun forever.

#include <curses.h>
#include <signal.h>

void handle_sig(int sig) {
    if (sig == SIGINT) {
        endwin();
        printf("End\n");
        exit(0);
    }
}

int main() {
    signal(SIGINT, handle_sig);
    initscr();
    while (1);
    return 0;
}

Solution

  • It seems that noraw() mode was never really implemented for the Windows console port of PDCurses. (It is in DOS and OS/2.) I was able to correct this, although a complete fix will require a bit more work.

    In the meantime, I suggest rewriting your program to handle Ctrl+C itself, if at all possible. Note that, even if noraw mode is fixed for wincon, it will probably never work in the PDCurses ports that don't depend on a controlling terminal.

    But if you want to patch your PDCurses:

    diff --git a/wincon/pdckbd.c b/wincon/pdckbd.c
    index d2c3ab69..9bfc8927 100644
    --- a/wincon/pdckbd.c
    +++ b/wincon/pdckbd.c
    @@ -215,7 +215,13 @@ static KPTAB ext_kptab[] =
     
     void PDC_set_keyboard_binary(bool on)
     {
    +    DWORD mode;
    +
         PDC_LOG(("PDC_set_keyboard_binary() - called\n"));
    +
    +    GetConsoleMode(pdc_con_in, &mode);
    +    SetConsoleMode(pdc_con_in, !on ? (mode | ENABLE_PROCESSED_INPUT) :
    +                                    (mode & ~ENABLE_PROCESSED_INPUT));
     }
     
     /* check if a key or mouse event is waiting */
    @@ -640,8 +646,8 @@ int PDC_mouse_set(void)
            If turning off the mouse: Set QuickEdit Mode to the status it
            had on startup, and clear all other flags */
     
    -    SetConsoleMode(pdc_con_in, SP->_trap_mbe ?
    -                   (ENABLE_MOUSE_INPUT|0x0088) : (pdc_quick_edit|0x0088));
    +    //SetConsoleMode(pdc_con_in, SP->_trap_mbe ?
    +    //               (ENABLE_MOUSE_INPUT|0x0088) : (pdc_quick_edit|0x0088));
     
         memset(&old_mouse_status, 0, sizeof(old_mouse_status));
    

    (This disables the mouse input toggle -- a quick and dirty patch.)