Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!mcsun!hp4nl!ruuinf!henkp From: henkp@ruuinf.cs.ruu.nl (Henk P. Penning) Newsgroups: comp.lang.perl Subject: Re: pipe to sort and back Message-ID: <3702@ruuinf.cs.ruu.nl> Date: 25 Aug 90 19:54:53 GMT References: <1990Aug24.145831.13299@DRD.Com> Organization: Utrecht University, Dept. of CS Lines: 69 In article <1990Aug24.145831.13299@DRD.Com> mark@DRD.Com (Mark Lawrence) writes: >I have some data I'm reading and before I write it on to the intended >recipient, I want to take a chunk of it and pipe it to sort and bring >sort's output back and then write that on. Any way to easily set up a >bi-directional file handle (or pair of filehandles) to accomplish that? # Here is my solution. # Subroutine open2(READHANDLE,WRITEHANDLE,arg,arg,...) expects # names of a READHANDLE and a WRITEHANDLE (as strings). # It sets up pipes, forks, and calls exec(arg,arg,...) in the child. # # The example should print the first few lines of the sorted passwd file. # # === HenkP === # # Henk P. Penning, Dept of Computer Science, Utrecht University. # Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands. # Telephone: +31-30-534106 # e-mail : henkp@cs.ruu.nl (uucp to hp4nl!ruuinf!henkp) # --------------------------------------------------- sub open2 # ( READHANDLE, WRITEHANDLE, argument(s) to exec() ) { local($p1,$p2,@execParms) = @_ ; eval "pipe($p1,APPOUT)" || die "open2 can't create pipe $p1/APPOUT" ; eval "pipe(APPIN,$p2)" || die "open2 can't create pipe APPIN/$p2" ; $open2Pid = fork ; if ( $open2Pid == 0 ) # CHILD { close($p1) || die "child can't close $p1" ; close($p2) || die "child can't close $p2" ; close(STDIN) || die "child can't close STDIN" ; close(STDOUT) || die "child can't close STDOUT" ; open(STDIN, "<&APPIN") || die "child can't redirect STDIN" ; open(STDOUT,">&APPOUT") || die "child can't redirect STDOUT" ; close(APPIN) || die "child can't close APPIN" ; close(APPOUT) || die "child can't close APPOUT" ; exec(@execParms) ; die "open2 can't exec " . join(' ',@execParms) ; } else # PARENT { close(APPIN) || die "open2 can't close APPIN" ; close(APPOUT) || die "open2 can't close APPOUT" ; } } sub flush # ( FILEHANDLE ) { $oldselect = select($_[0]) ; $oldpipe = $| ; $| = 1 ; print "" ; $| = $oldpipe ; select($oldselect) ; } $INP = 'INP' ; $OUT = 'OUT' ; &open2($INP,$OUT,'sort | head') ; open(PW,'/etc/passwd') || die "can't open /etc/passwd\n" ; while ($_ = ) { print OUT "out> $_" ; } close(OUT) || die "can't close OUT\n" ; while ( $_ = ) { print "