public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: Jacek Trzmiel <sc0rp@hot.pl>
To: "cygwin@cygwin.com" <cygwin@cygwin.com>
Subject: shutdown( socket, SHUT_WR ) - unexpected behaviour
Date: Sat, 01 May 2004 22:07:00 -0000	[thread overview]
Message-ID: <40941F92.1DDD3E67@hot.pl> (raw)


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/

             reply	other threads:[~2004-05-01 22:07 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-05-01 22:07 Jacek Trzmiel [this message]
2004-05-03 11:44 ` Corinna Vinschen
2004-05-04  2:19   ` Jacek Trzmiel
2004-05-04  2:55     ` Larry Hall
2004-05-04  9:27       ` Dave Korn
2004-05-04 10:00         ` Keith Moore
2004-05-05  0:40           ` Jacek Trzmiel
2004-05-05  2:05           ` shutdown( socket, SHUT_WR ) - unexpected behaviour - RESOLVED Jacek Trzmiel
2004-05-05  0:35         ` shutdown( socket, SHUT_WR ) - unexpected behaviour Jacek Trzmiel
2004-05-04 12:37     ` Hannu E K Nevalainen
2004-05-05  0:42       ` Jacek Trzmiel
2004-05-04  6:37 Arash Partow
2004-05-04  9:21 ` Dave Korn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=40941F92.1DDD3E67@hot.pl \
    --to=sc0rp@hot.pl \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).