tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: readv() on TCP socket returns 0



Thor Lancelot Simon <tls%panix.com@localhost> wrote:
 |On Thu, Mar 07, 2013 at 07:54:58PM +0100, Steffen Daode Nurpmeso wrote:
 |> Mouse <mouse%Rodents-Montreal.ORG@localhost> wrote:
 |>|> readv() returns 0 on EOF.  If the file descriptor is a TCP socket, I
 |>|> guess that means the connexion was closed,
 |>|
 |>|Not necessarily.  shutdown(...,SHUT_WR) (or the local equivalent) on
 |>  [.]
 |>|If you care about portability, I would recommend not counting on this.
 |> 
 |> shutdown(2) doesn't do that on Mac OS X; iirc it acts just like
 |> close(2), there.
 |
 |Are you saying you can't half-close a TCP connection on OS X?  I am
 |skeptical.

And you're damn right, that must have been a Python bug that i've
seen back in 2011, and even implemented a workaround for (after
painful debugging)!
Whereas the perl(1) script below shows the correct result:

  P: startup
  C: startup
  C: parent says: Hi, child
  P: child says: Hi, parental control!
  C: parent says: Say good night
  C: good bye.
  P: child says: You must be joking, right?
  P: good bye.

 |Thor

--steffen

use diagnostics -verbose;
use strict;
use warnings;

use IO::Handle;
use Socket;

our $CPID;

sub main_fun {
   STDOUT->autoflush(1);
   die "socketpair: $^E"
      unless socketpair(CP, PP, AF_UNIX, SOCK_STREAM, PF_UNSPEC);
   CP->autoflush(1);
   PP->autoflush(1);
   die "fork: $^E" unless defined($CPID = fork);
   Child::run(*CP) if $CPID == 0;
   Parent::run(*PP);
}

package Parent;
sub run {
   my ($s, $line) = ($_[0]);
   print "P: startup\n";
   _die("P->C print1") unless print $s "Hi, child\n";
   _die("P<-C readline1") unless defined($line = <$s>);
   print "P: child says: $line";
   _die("P->C print2") unless print $s "Say good night\n";
   shutdown($s, 1);
   _die("P<-C readline2") unless defined($line = <$s>);
   print "P: child says: $line";
   waitpid $CPID, 0;
   print "P: good bye.\n";
   exit 0;
}

sub _die {
   waitpid $CPID, 0;
   die "P: $_[0]\n";
}

package Child;
sub run {
   my ($s, $line) = ($_[0]);
   print "C: startup\n";
   die "C<-P readline1" unless defined($line = <$s>);
   print "C: parent says: $line";
   die "C->P print1" unless print $s "Hi, parental control!\n";
   die "C<-P readline2" unless defined($line = <$s>);
   print "C: parent says: $line";
   die "C->P print2" unless print $s "You must be joking, right?\n";
   print "C: good bye.\n";
   exit 0;
}

{package main; main_fun();}
# vim:set fenc=utf-8 syntax=perl ts=3 sts=0 sw=3 et tw=79: s-it-mode


Home | Main Index | Thread Index | Old Index