Hi, $ cygcheck -cd cygwin Cygwin Package Information Package Version cygwin 1.5.9-1
I found some unexpected behaviour of shutdown call. Here is example program to reproduce problem. It is supposed to send simple http request to example.org, close writing part of socket, and then wait for and print reply: --- ShutdownTest.cpp ------------------------------------------------ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <string.h> #include <assert.h> const char *HOST = "example.org"; const int PORT = 80; const char *MESSAGE = "GET / HTTP/1.0\r\n\r\n"; void sendall( int sd, const char *data, int datalen ) { assert( data ); assert( datalen >= 0 ); while(datalen>0) { int sent = send(sd, data, datalen, 0); if( sent == -1) { perror("send"); exit(1); } data += sent; datalen -= sent; assert( datalen>=0 ); } } void recvandprintall( int sd ) { const int bufferlen = 65536; char buffer[bufferlen]; while(true) { int got = recv(sd, buffer, bufferlen, 0); if(got == -1) { perror("recv"); exit(1); } if(got==0) { break; } for( int i=0; i<got; ++i) { printf( "%c", buffer[i] ); } } } void test() { /* go find out about the desired host machine */ struct hostent *he = gethostbyname(HOST); if (he == 0) { perror("gethostbyname"); exit(1); } assert( he->h_addrtype == AF_INET ); assert( he->h_addr_list[0] ); /* fill in the socket structure with host information */ struct sockaddr_in pin; memset( &pin, 0, sizeof(pin) ); pin.sin_family = AF_INET; pin.sin_addr.s_addr = ((struct in_addr *)(he->h_addr))->s_addr; pin.sin_port = htons(PORT); /* grab an Internet domain socket */ int sd; if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } /* connect to PORT on HOST */ if (connect(sd,(struct sockaddr *) &pin, sizeof(pin)) == -1) { perror("connect"); exit(1); } /* send a message to the server PORT on machine HOST */ sendall( sd, MESSAGE, strlen(MESSAGE) ); /* shutdown writing part of socket */ shutdown( sd, SHUT_WR ); /* wait for data to come back from the server and print it */ recvandprintall( sd ); close(sd); } int main() { test(); return 0; } --- ShutdownTest.cpp ------------------------------------------------ If you compile and run it this way: $ g++ ShutdownTest.cpp -o ShutdownTest && ./ShutdownTest.exe it doesn't print anything. Commenting out shutdown call or adding some wait before it does make program work as expected: $ g++ ShutdownTest.cpp -o ShutdownTest && ./ShutdownTest.exe HTTP/1.1 200 OK Date: Sat, 01 May 2004 23:28:20 GMT Server: Apache/1.3.27 (Unix) (Red-Hat/Linux) Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT [...] 1. I suppose that shutdown(sd,SHUT_WR) does not force unflushed buffers out (i.e. discards them). Am I right? 2. Is this bug or feature? Manual page isn't helpful: $ man 2 shutdown No entry for shutdown in section 2 of the manual $ man shutdown No manual entry for shutdown 3. If it's a feature, then how can I manually flush buffers out before calling shutdown? I've googled for this problem, but haven't found any relevant information. Best regards, Jacek. -- 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/