On 12/08/2009 13:54, Jon TURNEY wrote:
Hmmm... but if it's really the size of the sockname argument which is
causing the accept() to fail, this would be a bug in cygwin's accept()
implementation, as it's supposed to truncate the data written to the
sockname, rather than fail if it won't fit [1]. If that actually is the
case, since we don't actually use the peer address here, the code as
stands is correct (if a little odd).
I suppose I need to write a small test case to look at this...
[1] http://www.opengroup.org/onlinepubs/009695399/functions/accept.html
A couple of small programs which hopefully demonstrate this problem.
(As is, the connection fails, but uncommenting the alternate definition of
cliaddr in listener.c allows it to work)
I'd hazard a guess that perhaps this is because the underlying winsock
accept() doesn't have this truncate behaviour and considers a too-small
address_len an error.
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <netinet/in.h>
//
// gcc connector.c -o connector
//
int
main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in6 servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin6_family = AF_INET6;
servaddr.sin6_addr = in6addr_loopback;
servaddr.sin6_port = htons(13); /* daytime server */
if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0)
{
printf("socket error\n");
exit(1);
}
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
{
printf("connect error\n");
exit(1);
}
}
#include <stdio.h>
#include <strings.h>
#include <netinet/in.h>
//
// gcc listener.c -o listener
//
int
main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t len;
struct sockaddr_in6 servaddr;
struct sockaddr_in cliaddr;
// struct sockaddr_in6 cliaddr;
listenfd = socket(AF_INET6, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin6_family = AF_INET6;
servaddr.sin6_addr = in6addr_any;
servaddr.sin6_port = htons(13); /* daytime server */
bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
listen(listenfd, 5);
for (;;)
{
len = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &len);
if (connfd > 0)
{
printf("accept() succeeded\n");
}
else
{
printf("accept() failed\n");
}
}
}
--
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