X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FIPC%2FOpen3.pm;h=95313fce3d95f8f3355c49b1b5248dd20edd8ee6;hb=fe98d82b2e4171a609025e7b159d7945efe2900c;hp=da925182e77c76718871e37a7939f6f10ab2ec52;hpb=20a6717b3f0310570b661870c2455994a4ab8016;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/IPC/Open3.pm b/lib/IPC/Open3.pm index da92518..95313fc 100644 --- a/lib/IPC/Open3.pm +++ b/lib/IPC/Open3.pm @@ -9,7 +9,7 @@ require Exporter; use Carp; use Symbol qw(gensym qualify); -$VERSION = 1.0106; +$VERSION = 1.02; @ISA = qw(Exporter); @EXPORT = qw(open3); @@ -19,7 +19,7 @@ IPC::Open3, open3 - open a process for reading, writing, and error handling =head1 SYNOPSIS - $pid = open3(\*WTRFH, \*RDRFH, \*ERRFH, + $pid = open3(\*CHLD_IN, \*CHLD_OUT, \*CHLD_ERR, 'some cmd and args', 'optarg', ...); my($wtr, $rdr, $err); @@ -29,15 +29,17 @@ IPC::Open3, open3 - open a process for reading, writing, and error handling =head1 DESCRIPTION Extremely similar to open2(), open3() spawns the given $cmd and -connects RDRFH for reading, WTRFH for writing, and ERRFH for errors. If -ERRFH is false, or the same file descriptor as RDRFH, then STDOUT and -STDERR of the child are on the same filehandle. The WTRFH will have -autoflush turned on. - -If WTRFH begins with C<< <& >>, then WTRFH will be closed in the parent, and -the child will read from it directly. If RDRFH or ERRFH begins with -C<< >& >>, then the child will send output directly to that filehandle. -In both cases, there will be a dup(2) instead of a pipe(2) made. +connects CHLD_OUT for reading from the child, CHLD_IN for writing to +the child, and CHLD_ERR for errors. If CHLD_ERR is false, or the +same file descriptor as CHLD_OUT, then STDOUT and STDERR of the child +are on the same filehandle. The CHLD_IN will have autoflush turned +on. + +If CHLD_IN begins with C<< <& >>, then CHLD_IN will be closed in the +parent, and the child will read from it directly. If CHLD_OUT or +CHLD_ERR begins with C<< >& >>, then the child will send output +directly to that filehandle. In both cases, there will be a dup(2) +instead of a pipe(2) made. If either reader or writer is the null string, this will be replaced by an autogenerated filehandle. If so, you must pass a valid lvalue @@ -49,8 +51,12 @@ as file descriptors. open3() returns the process ID of the child process. It doesn't return on failure: it just raises an exception matching C. However, -C failures in the child are not detected. You'll have to -trap SIGPIPE yourself. +C failures in the child (such as no such file or permission denied), +are just reported to CHLD_ERR, as it is not possible to trap them. + +If the child process dies for any reason, the next write to CHLD_IN is +likely to generate a SIGPIPE in the parent, which is fatal by default. +So you may wish to handle this signal. Note if you specify C<-> as the command, in an analogous fashion to C the child process will just be the forked Perl @@ -81,6 +87,21 @@ over source code being run in the child process, you can't control what it does with pipe buffering. Thus you can't just open a pipe to C and continually read and write a line from it. +=head1 See Also + +=over 4 + +=item L + +Like Open3 but without STDERR catpure. + +=item L + +This is a CPAN module that has better error handling and more facilities +than Open3. + +=back + =head1 WARNING The order of arguments differs from that of open2(). @@ -162,6 +183,10 @@ sub _open3 { my($package, $dad_wtr, $dad_rdr, $dad_err, @cmd) = @_; my($dup_wtr, $dup_rdr, $dup_err, $kidpid); + if (@cmd > 1 and $cmd[0] eq '-') { + croak "Arguments don't make sense when the command is '-'" + } + # simulate autovivification of filehandles because # it's too ugly to use @_ throughout to make perl do it for us # tchrist 5-Mar-00 @@ -235,14 +260,13 @@ sub _open3 { } else { xopen \*STDERR, ">&STDOUT" if fileno(STDERR) != fileno(STDOUT); } - if ($cmd[0] eq '-') { - croak "Arguments don't make sense when the command is '-'" - if @cmd > 1; - return 0; - } + return 0 if ($cmd[0] eq '-'); local($")=(" "); - exec @cmd # XXX: wrong process to croak from - or croak "$Me: exec of @cmd failed"; + exec @cmd or do { + carp "$Me: exec of @cmd failed"; + eval { require POSIX; POSIX::_exit(255); }; + exit 255; + }; } elsif ($do_spawn) { # All the bookkeeping of coincidence between handles is # handled in spawn_with_handles.