Path: utzoo!utgpu!watserv1!watmath!att!rutgers!cs.utexas.edu!usc!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: open pipe in and out Keywords: perl pipe Message-ID: <8747@jpl-devvax.JPL.NASA.GOV> Date: 16 Jul 90 18:24:21 GMT References: <250@carssdf.UUCP> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 59 In article <250@carssdf.UUCP> usenet@carssdf.UUCP (John Watson) writes: : I have a perl script that needs to send a few lines to a filter : process and read a few lines back. (I have no sockets, forget that.) : I would like to do something like pipe, fork, exec, dup2, etc... : The way I do it in "c". But the key here is that I need to be able : to use something like dup2 to make the pipe in and pipe out handles : look like STDIN and STDOUT to the child process before I do the exec. : I would like to retain the filter aspect, reads STDIN, writes STDOUT, : of the child process. If that were not possible, I would still need : a way to pass the file handle numbers (the fd ints, not the *FILE's). Here's a simple-minded routine. It could be extended to use (or generate) arbitrary filehandles, but for this one you just write to W1 and read from R2. Don't try to write more than 4096 bytes, of course, or you'll deadlock... #!/usr/bin/perl sub filter { pipe(R1,W1); pipe(R2,W2); local($pid) = fork; if (!defined($pid)) { close R1; close R2; close W1; close W2; } elsif ($pid) { close R1; close W2; } else { close W1; close R2; open(STDIN,">&R1") || die "Can't dup to STDIN: $!\n"; open(STDOUT,">&W2") || die "Can't dup to STDOUT: $!\n"; close R1; close W2; print STDERR "execing @_\n"; exec @_; die "Can't exec @_: $!\n"; } $pid; } &filter('tr a-z A-Z'); while (<>) { print W1 $_; } close W1; while () { print; } Larry Wall lwall@jpl-devvax.jpl.nasa.gov