This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

write big buffer to connected socket, then close socket hangs cygwin


Latest updated cygwin (just updated to make sure), Windows Vista SP1.

This will hang cygwin 1.5.25-cr-0x5f1:
1. Create a connected socket
2. Send a big enough buffer (> 0x4238 bytes)
3. Close the socket

It will hang in the close() function. Only way is to kill it with
taskmanager or close the cygwin window. Source code is attached.
$ gcc bug.c -o bug && ./bug
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>

int setNonBlock(int sock)
{
	if (fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK) == -1)
	{
		perror("set non-block");
		exit(1);
	}
	return 1;
}

int main()
{
	int sock1, sock2, socklisten;
	struct sockaddr_in sa;
	socklen_t saLen;
	/* Anything > 0x4238 will hang cygwin. Tested Vista SP1, cygwin1.dll
	   file version 1005.25.0.0, product version 1.5.25-cr-0x5f1
	   CYGWIN_NT-6.0 bbqpc 1.5.25(0.156/4/2) 2008-06-12 19:34 i686 Cygwin
	*/
	char buf[0x4238 + 1];

	memset(&sa, 0, sizeof(sa));
	sa.sin_family = AF_INET;
	sa.sin_port = htons(1234);
	sa.sin_addr.s_addr = htonl(0x7F000001);
	saLen = sizeof(sa);
	if ((socklisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1 ||
		!setNonBlock(socklisten) ||
		bind(socklisten, (struct sockaddr*)&sa, sizeof(sa)) == -1 ||
		listen(socklisten, 5) == -1 ||
		getsockname(socklisten, (struct sockaddr*)&sa, &saLen) == -1 ||
		(sock1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1 ||
		!setNonBlock(sock1) ||
		(connect(sock1, (struct sockaddr*)&sa, sizeof(sa)) == -1 && errno != EINPROGRESS))
	{
		perror("socket init");
		exit(1);
	}

	printf("Trying to accept()\n");
	while ((sock2 = accept(socklisten, 0, 0)) == -1)
		/* wait */;

	printf("Sending\n");
	while (send(sock1, buf, sizeof(buf), 0) == -1)
	{
		if (errno != EALREADY)
		{
			perror("send");
			exit(1);
		}
	}

	printf("Closing\n");
	close(sock1);

	printf("OK\n");
	return 0;
}
--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]