select() not interrupted by signals

Thomas Wolff towo@towo.net
Fri Jan 11 08:41:00 GMT 2013


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
-------------- next part --------------
#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);
	}
}


-------------- next part --------------
--
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


More information about the Cygwin mailing list