I have a problem with ncurses and couldn't find a solution on the web, so I've written following little program to demonstrate the problem.
You can compile it via:
sudo aptitude install ncurses-dev
g++ -lncurses -o resize resize.cpp
It displays an integer counter incremented every second by forking into a timer process which periodically sends one byte to the parent process via a socketpair. You can quit it by pressing CTRL+C.
When you resize the terminal you should get an error message of 'Interrupted system call'. So the read call gets interrupted by SIGWINCH when resizing. But how can I avoid this? Or is it common that the system call gets interrupted? But how would I handle an interrupted system call in order to proceed incrementing the counter since the file descripter appears to be dead after interruption.
If you use non-blocking sockets, you would get 'Resource temporarily unavailable' instead.
I am using stable debian wheezy, so the ncurses version is 5.9-10 and the libstdc++ version is 4.7.2-5.
#include <ncurses.h>
#include <signal.h>
#include <netdb.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <string>
#include <iostream>
//Define a second.
timespec span = {1, 0};
//Handles both, SIGWINCH and SIGINT
void handle(int signal) {
    switch (signal) {
        case SIGWINCH:
            //Reinitialize ncurses to get new size
            endwin();
            refresh();
            printw("Catched SIGWINCH and handled it.\n");
            refresh();
        break;
        case SIGINT:
            //Catched CTRL+C and quit
            endwin();
            exit(0);
        break;
    }
}
//This registers above signal handler function
void set_handler_for(int signal) {
    struct sigaction action;
    action.sa_handler = handle;
    action.sa_flags = 0;
    if (-1 == sigemptyset(&action.sa_mask) or -1 == sigaction(signal, &action, NULL))
        throw "Cannot set signal handler";
}
main() {
    int fd[2];
    //In this try block we fork into the timer process
    try {
        set_handler_for(SIGINT);
        set_handler_for(SIGWINCH);
        //Creating a socketpair to communicate between timer and parent process
        if (-1 == socketpair(PF_LOCAL, SOCK_STREAM, 0, fd))
            throw "Cannot create socketpair";
        pid_t pid;
        //Doing the fork
        if (-1 == (pid = fork()))
            throw "Cannot fork process";
        if (!pid) {
            //We are the timer, so closing the other end of the socketpair
            close(fd[0]);
            //We send one byte every second to the parent process
            while (true) {
                char byte;
                ssize_t bytes = write(fd[1], &byte, sizeof byte);
                if (0 >= bytes)
                    throw "Cannot write";
                nanosleep(&span, 0);
            }
            //Here the timer process ends
            exit(0);
        }
        //We are the parent process, so closing the other end of the socketpair
        close(fd[1]);
    }
    catch (const char*& what) {
        std::cerr << what << std::endl;
        exit(1);
    }
    //Parent process - Initializing ncurses
    initscr();
    noecho();
    curs_set(0);
    nodelay(stdscr, TRUE);
    //In this try block we read (blocking) the byte from the timer process every second
    try {
        int tick = 0;
        while (true) {
            char byte;
            ssize_t bytes = read(fd[0], &byte, sizeof byte);
            if (0 >= bytes)
                throw "Cannot read";
            //Clear screen and print increased counter
            clear();
            mvprintw(0, 0, "Tick: %d - Resize terminal and press CTRL+C to quit.\n", ++tick);
            //Catch special key KEY_RESIZE and reinitialize ncurses to get new size (actually not necassary)
            int key;
            while ((key = getch()) != ERR) {
                if (key == KEY_RESIZE) {
                    endwin();
                    refresh();
                    printw("Got KEY_RESIZE and handled it.\n");
                }
            }
            //Update the screen
            refresh();
        }
    }
    catch (const char*& what) {
        //We got an error - print it but don't quit in order to have time to read it
        std::string error(what);
        if (errno) {
            error.append(": ");
            error.append(strerror(errno));
        }
        error = "Catched exception: "+error+"\n";
        printw(error.c_str());
        refresh();
        //Waiting for CTRL+C to quit
        while (true)
            nanosleep(&span, 0);
    }
}
Thank you!
Regards
                        
Most (if not all) system calls have an interrupted error code (errno == EINTR), this is normal.
I would check for EINTR on the read from the pipe and ignore it, just read again.
I wouldn't call any ncurses functions in the signal handler, some are re-entrant but I doubt printw is. Just do the KEY_RESIZE check.