Problem with accept(2) on the 1003.20.0.0 release

jeff_burch@agilent.com jeff_burch@agilent.com
Thu Feb 13 22:29:00 GMT 2003


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@agilent.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/



More information about the Cygwin mailing list