[LWN Logo]

From: Tom Christiansen <tchrist@mox.perl.com>
Subject: SRC: full duplex comminication with socketpair
Date: 22 May 1998 14:01:39 GMT

Here's an example of a parent and child in full-duplex communication:

    #!/usr/bin/perl -w
    #  bidirectional communication using socketpair
    #   "the best ones always go both ways"

    use Socket;
    use IO::Handle;
    socketpair(CHILD, PARENT, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
	||  die "socketpair: $!";

    CHILD->autoflush(1);
    PARENT->autoflush(1);

    if ($pid = fork) {
	close PARENT;
	print CHILD "Parent Pid $$ is sending this\n";
	chomp($line = <CHILD>);
	print "Parent Pid $$ just read this: `$line'\n";
	close CHILD;
	waitpid($pid,0);
    } else {
	die "cannot fork: $!" unless defined $pid;
	close CHILD;
	chomp($line = <PARENT>);
	print "Child Pid $$ just read this: `$line'\n";
	print PARENT "Child Pid $$ is sending this\n";
	close PARENT;
	exit;
    }

Some systems have historically implemented pipes as two
half-closed ends of a socketpair.  They essentially define 
pipe(READER, WRITER) this way:

    socketpair(READER, WRITER, AF_UNIX, SOCK_STREAM, PF_UNSPEC);
    shutdown(READER, 1);	# no more writing for reader
    shutdown(WRITER, 0);	# no more reading for writer

(NB: On Linux kernels before 2.0.34, the shutdown(2) system call was
broken.)

If you don't have socketpair, but do have pipe (do these people exist?),
you can do this:

    #!/usr/bin/perl -w
    use IO::Handle;
    pipe(PARENT_RDR, CHILD_WTR);
    pipe(CHILD_RDR,  PARENT_WTR);
    CHILD_WTR->autoflush(1);
    PARENT_WTR->autoflush(1);

    if ($pid = fork) {
	close PARENT_RDR; close PARENT_WTR;
	print CHILD_WTR "Parent Pid $$ is sending this\n";
	chomp($line = <CHILD_RDR>);
	print "Parent Pid $$ just read this: `$line'\n";
	close CHILD_RDR; close CHILD_WTR;
	waitpid($pid,0);
    } else {
	die "cannot fork: $!" unless defined $pid;
	close CHILD_RDR; close CHILD_WTR;
	chomp($line = <PARENT_RDR>);
	print "Child Pid $$ just read this: `$line'\n";
	print PARENT_WTR "Child Pid $$ is sending this\n";
	close PARENT_RDR; close PARENT_WTR;
	exit;
    }

--tom
-- 
Tactical?  TACTICAL!?!?  Hey, buddy, we went from kilotons to megatons
several minutes ago.  We don't need no stinkin' tactical nukes.
(By the way, do you have change for 10 million people?) --lwall