0
votes

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();
    }
}
1
Do you have a handler for SIG_ALRM? The documentation says "Under the ncurses implementation, handled signals never interrupt getch." - Barmar
This is my handler for SIG_ALRM Is your update() function async-signal-safe? - Andrew Henle
I'm very new to C and didn't know that concept. I'm reading about it and I'm not sure but it probably isn't. Basically my update() function calls malloc and some curses functions like wmove, winch, and printw. It also sets some data that is used by the main loop. If printf and other buffered IO functions are unsafe, I suppose the ncurses counterparts are also unsafe. - JonPC

1 Answers

1
votes

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) {
        ...
    }
}