open() and pipes

lists@notatla.org.uk lists at notatla.org.uk
Wed Aug 2 10:21:26 BST 2006


From: David Cantrell <david at cantrell.org.uk>

> Defnitly not what I need then.  All I want to do is replace this ugly
> hack ...
> 
>   open(FOO), '|myprogram outputfile=foo.tmp');
>   print FOO 'munge this';
>   close(FOO);
>   # at this point some naughty chap replaces foo.tmp just to piss me off
>   open(FOORESULTS, 'foo.tmp');
>   my $munged = <FOORESULTS>;
>   close(FOORESULTS);
>   unlink 'foo.tmp';
> 
> with this ...
> 
>   open(FOO, '|myprogram|');
>   print FOO, 'munge this';
>   my $munged = <FOO>;
>   close(FOO);

I use two pipes which probably isn't the prettiest thing you'll
see today but it works.  It's also what I'd expect to do in C.
I haven't looked at what procmail source does for this.  Does
it use just one pipe and the parent calls shutdown() when it's
finished writing?

#    Use two pipes (and 4 handles).
pipe(DOWNRH,DOWNWH) or die();
pipe(UPRH,UPWH) or die();
$pid=fork();
die() unless defined($pid);
if ($pid) {
    # parent writes something
    close(DOWNRH);
    printf(DOWNWH "ABCD\nEFGH\nIJKL\n");
    close(DOWNWH);
    # parent has stopped writing
    close(UPWH);
    # parent reads something
    while (<UPRH>) {
         printf("tr told me: %s", $_);
    }
    close(UPRH);
    waitpid($pid, 0);
} else {
    # tr is just an example, wouldn't normally call an external prog
    close(DOWNWH);
    close(UPRH);
    open(STDIN, "<&DOWNRH")  or die();
    open(STDOUT, ">&UPWH")  or die();
    exec("/usr/bin/tr", "[:upper:]", "[:lower:]") or die("exec tr");
}



More information about the london.pm mailing list