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:   [EMAIL PROTECTED]


--
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/

Reply via email to