Mail Archives: cygwin/2003/02/13/16:59:22
Dear Cygwin community,
I just upgraded my cygwin from 1003.19.0.0 (build data 2003-01-23 21:31) to 1003.20.0.0 (build data 2003-02-08 12:10) and have a major problem with accept(2). On the first connection to a network port, all is well. Accept( ) returns and all works as expected. On the second call to accept( ) I get into trouble. Accept( ) NEVER returns!
It doesn't appear to matter where I build the .exe file. Only when running the .exe on my 1003.20.0.0 release do I have this problem. Running it on the 1003.19.0.0 release, all is well...
Attached is a simple program that illustrates the problem.
/*
Test cygwin's implementation of select( ) / accept( )
A problem occurs on the second pass through the select/accept loop.
This was noticed on the 1003.20.0.0 cygwin release and was not present
in the 1003.19.0.0 release
Build:
g++ -g -o testAccept testAccept.cpp
Run in one cygwin window. In a second cygwin window, execute the following:
telnet localhost 5432 <== first connection is OK
Trying 127.0.0.1...
Connected to xxyzzy.somewhere.com
Escape character is '^]'.
Connection closed by foreign host.
telnet localhost 5432 <== second connection hangs
Trying 127.0.0.1...
Connected to xxyzzy.somewhere.com
Escape character is '^]'.
Program output:
Calling select() with socket 3
select returned 1
our socket has a connection
calling accept <== first accept() is fine
accept returned 4
inetd.cpp: connection from IP=127.0.0.1, port 4208
Calling select() with socket 3
select returned 1
our socket has a connection
calling accept <== program hangs here...
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main( int argc, char *argv[])
{
fd_set readfd;
struct sockaddr_in lsocket;
int nfound;
int one=1;
int fd;
memset( &lsocket, 0, sizeof(lsocket));
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = htons(5432) ; // Caution: hard-coded port number
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0)
{
printf("Can't open socket\n");
return -1;
}
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) ;
lsocket.sin_family = AF_INET;
if (bind(fd, (struct sockaddr *)&lsocket, sizeof(lsocket)) != 0)
{
printf("Can't bind socket\n");
return -1;
}
listen(fd, 9);
FD_SET( fd, &readfd);
while (1) // loop forever...
{
printf("Calling select() with socket %d\n", fd);
nfound = select( fd+1, &readfd, 0, 0, 0);
printf("select returned %d\n", nfound);
switch (nfound)
{
case 0:
/* select timeout error! */
printf("select timeout\n");
break ;
case -1:
/* select error */
printf("select error\n");
break;
default:
/* we have someone trying to make a connection! */
if (FD_ISSET(fd, &readfd))
{
printf("our socket has a connection\n");
struct sockaddr_in fromAddr;
socklen_t fromAddrLen = sizeof(fromAddr);
// The problem occurs in the following call to accept( ) on the
// second pass through the loop
printf("calling accept\n");
int s = accept(fd, (struct sockaddr *)&fromAddr, &fromAddrLen) ;
printf("accept returned %d\n", s);
if (s >=0)
{
int addr = ntohl(fromAddr.sin_addr.s_addr);
printf("connection from IP=%d.%d.%d.%d, port %d\n",
(addr >> 24) & 0xff, (addr >> 16) & 0xff,
(addr >> 8) & 0xff, (addr >> 0) & 0xff,
ntohs(fromAddr.sin_port));
// We don't do anything useful with the connection...
// We don't read or write anything but this doesn't appear
// to matter. My real application does tons of socket IO...
shutdown( s, SHUT_WR);
shutdown( s, SHUT_RD);
}
}
else
{
printf("some other socket has a connection\n");
}
} // end switch
} // end while
return 0;
}
Jeff Burch
Communications Solutions Department
Agilent Laboratories
Phone: 650-485-6364
Fax: 650-485-8092
email: jeff_burch AT agilent DOT com
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Bug reporting: http://cygwin.com/bugs.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
- Raw text -