Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-ID: <40941F92.1DDD3E67@hot.pl> Date: Sun, 02 May 2004 00:07:14 +0200 From: Jacek Trzmiel MIME-Version: 1.0 To: "cygwin AT cygwin DOT com" Subject: shutdown( socket, SHUT_WR ) - unexpected behaviour Content-Type: text/plain; charset=iso-8859-2 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes 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 #include #include #include #include #include #include #include #include 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; ih_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/