This is the mail archive of the
cygwin
mailing list for the Cygwin project.
write big buffer to connected socket, then close socket hangs cygwin
- From: "kalle ko" <cocalle at gmail dot com>
- To: cygwin at cygwin dot com
- Date: Tue, 15 Jul 2008 17:35:55 +0200
- Subject: 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/