I had previously reported "select() hanging after terminal killed" (http://cygwin.com/ml/cygwin/2011-05/msg00418.html). It turns out that select() does not get interrupted by a SIGWINCH signal either (with likely the same cause). This raises problems with interactive programs that want to react to window size changes (like text editors).

See attached updated test case; run the program, while select() is waiting (before 5 second timeout each), change window size and see no interrupt. On other systems, select() is interrupted (test case: from mintty, remote login to SunOS; also showing the terminal is not involved in the problem).

This bug did not exist in cygwin 1.5; I see some Changelog entries from 2011-12-13 or 2012-01-22 which might be related.
------
Thomas
#include <stdio.h>
#include <stdlib.h>

#include <sys/select.h>
#include <errno.h>

#include <signal.h>

int
peek (int fd, int msec)
{
        fd_set readfds;
        fd_set exceptfds;
        struct timeval timeoutstru;
        int nfds;

        FD_ZERO (& readfds);
        FD_SET (fd, & readfds);
        FD_ZERO (& exceptfds);
        FD_SET (fd, & exceptfds);
        timeoutstru.tv_sec = msec / 1000;
        timeoutstru.tv_usec = (msec % 1000) * 1000;

        errno = 0;
        printf ("calling select\n");
        nfds = select (fd + 1, & readfds, 0, & exceptfds, & timeoutstru);
        printf ("select -> %d (%s), read %02X except %02X\n", 
                nfds, strerror (errno), readfds, exceptfds);

        return nfds;
}

void
catch_HUP (int hup)
{
        printf ("HUP\n");
        signal (SIGHUP, catch_HUP);
}

void
catch_WINCH (int hup)
{
        printf ("WINCH\n");
        signal (SIGWINCH, catch_WINCH);
}

int
main ()
{
        int fdstdin = 0;

        system ("stty -icanon");
        signal (SIGHUP, catch_HUP);
        signal (SIGWINCH, catch_WINCH);

        while (1) {
                char buf;
                int buflen = 1;

                int nfds = peek (fdstdin, 5000);
                if (nfds > 0) {
                        int n;

                        printf ("calling read\n");
                        errno = 0;
                        n = read (fdstdin, & buf, buflen);
                        if (n <= 0) {
                                printf ("read -> %d (%s); exit\n", n, strerror 
(errno));
                                exit (0);
                        }
                        printf ("read -> %d: %c\n", n, buf);
                }
                sleep (2);
        }
}


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply via email to