Search code examples
cncurses

ncurses getch() behaviour with signals


My code sets a timer that sends a SIG_ALRM every x seconds. Then it enters a input-handling loop where it calls getch().

    int total_keys = 0;
    while (1) {
        inputchar = wgetch(mywindow);
        mvprintw(LINES - 2, 2, "%d", total_keys++);
        refresh();
        switch (inputchar) {
            ...
        }
    }

Since I set getch() to be blocking (wtimeout(mywindow, -1);), I expected total_keys to only go up when I press a key, but I found that every time the SIG_ALRM is received, getch() returns and total_keys increments. Does anyone know why this works this way?

Edit: This is my handler for SIG_ALRM

void alarm_handler(int signum, siginfo_t *si, void *ucontext) {
    timer_t *timeridp = si->si_value.sival_ptr;
    if (*timeridp == *update_timerp) {
        update();
    }
}

Solution

  • Check for an error return and don't process the input when this happens.

    while (1) {
        inputchar = wgetch(mywindow);
        if (inputchar == ERR) {
            if (errno == EINTR) {
                continue;
            } else {
                // report failure somehow
            }
        }
        mvprintw(LINES - 2, 2, "%d", ++total_keys);
        refresh();
        switch (inputchar) {
            ...
        }
    }