various pod nits (from Larry Virden and others)
[p5sagit/p5-mst-13.2.git] / lib / IPC / Open3.pm
CommitLineData
a0d0e21e 1package IPC::Open3;
7e1af8bc 2
3use strict;
4no strict 'refs'; # because users pass me bareword filehandles
2675ae2b 5our ($VERSION, @ISA, @EXPORT);
7e1af8bc 6
a0d0e21e 7require Exporter;
7e1af8bc 8
a0d0e21e 9use Carp;
8b3e92c6 10use Symbol qw(gensym qualify);
7e1af8bc 11
8b3e92c6 12$VERSION = 1.0103;
7e1af8bc 13@ISA = qw(Exporter);
14@EXPORT = qw(open3);
a0d0e21e 15
f06db76b 16=head1 NAME
17
18IPC::Open3, open3 - open a process for reading, writing, and error handling
19
20=head1 SYNOPSIS
21
84902520 22 $pid = open3(\*WTRFH, \*RDRFH, \*ERRFH,
f06db76b 23 'some cmd and args', 'optarg', ...);
24
2675ae2b 25 my($wtr, $rdr, $err);
26 $pid = open3($wtr, $rdr, $err,
27 'some cmd and args', 'optarg', ...);
28
f06db76b 29=head1 DESCRIPTION
30
31Extremely similar to open2(), open3() spawns the given $cmd and
32connects RDRFH for reading, WTRFH for writing, and ERRFH for errors. If
2675ae2b 33ERRFH is false, or the same file descriptor as RDRFH, then STDOUT and
34STDERR of the child are on the same filehandle. The WTRFH will have
35autoflush turned on.
f06db76b 36
2675ae2b 37If WTRFH begins with C<< <& >>, then WTRFH will be closed in the parent, and
4633a7c4 38the child will read from it directly. If RDRFH or ERRFH begins with
2675ae2b 39C<< >& >>, then the child will send output directly to that filehandle.
a24d8dfd 40In both cases, there will be a dup(2) instead of a pipe(2) made.
f06db76b 41
2675ae2b 42If either reader or writer is the null string, this will be replaced
43by an autogenerated filehandle. If so, you must pass a valid lvalue
44in the parameter slot so it can be overwritten in the caller, or
45an exception will be raised.
cb1a09d0 46
7e1af8bc 47open3() returns the process ID of the child process. It doesn't return on
2675ae2b 48failure: it just raises an exception matching C</^open3:/>. However,
49C<exec> failures in the child are not detected. You'll have to
50trap SIGPIPE yourself.
f06db76b 51
4375e838 52open3() does not wait for and reap the child process after it exits.
227e8dd4 53Except for short programs where it's acceptable to let the operating system
54take care of this, you need to do this yourself. This is normally as
55simple as calling C<waitpid $pid, 0> when you're done with the process.
56Failing to do this can result in an accumulation of defunct or "zombie"
57processes. See L<perlfunc/waitpid> for more information.
58
2675ae2b 59If you try to read from the child's stdout writer and their stderr
60writer, you'll have problems with blocking, which means you'll want
61to use select() or the IO::Select, which means you'd best use
62sysread() instead of readline() for normal stuff.
63
64This is very dangerous, as you may block forever. It assumes it's
65going to talk to something like B<bc>, both writing to it and reading
66from it. This is presumably safe because you "know" that commands
67like B<bc> will read a line at a time and output a line at a time.
68Programs like B<sort> that read their entire input stream first,
7e1af8bc 69however, are quite apt to cause deadlock.
70
71The big problem with this approach is that if you don't have control
7a2e2cd6 72over source code being run in the child process, you can't control
7e1af8bc 73what it does with pipe buffering. Thus you can't just open a pipe to
74C<cat -v> and continually read and write a line from it.
75
2675ae2b 76=head1 WARNING
77
78The order of arguments differs from that of open2().
79
7e1af8bc 80=cut
a0d0e21e 81
82# &open3: Marc Horowitz <marc@mit.edu>
83# derived mostly from &open2 by tom christiansen, <tchrist@convex.com>
4633a7c4 84# fixed for 5.001 by Ulrich Kunitz <kunitz@mai-koeln.com>
f55ee38a 85# ported to Win32 by Ron Schmidt, Merrill Lynch almost ended my career
2675ae2b 86# fixed for autovivving FHs, tchrist again
a0d0e21e 87#
88# $Id: open3.pl,v 1.1 1993/11/23 06:26:15 marc Exp $
89#
90# usage: $pid = open3('wtr', 'rdr', 'err' 'some cmd and args', 'optarg', ...);
91#
92# spawn the given $cmd and connect rdr for
93# reading, wtr for writing, and err for errors.
94# if err is '', or the same as rdr, then stdout and
95# stderr of the child are on the same fh. returns pid
7e1af8bc 96# of child (or dies on failure).
a0d0e21e 97
98
4633a7c4 99# if wtr begins with '<&', then wtr will be closed in the parent, and
a0d0e21e 100# the child will read from it directly. if rdr or err begins with
101# '>&', then the child will send output directly to that fd. In both
102# cases, there will be a dup() instead of a pipe() made.
103
104
105# WARNING: this is dangerous, as you may block forever
106# unless you are very careful.
107#
108# $wtr is left unbuffered.
109#
110# abort program if
111# rdr or wtr are null
7e1af8bc 112# a system call fails
a0d0e21e 113
2675ae2b 114our $Me = 'open3 (bug)'; # you should never see this, it's always localized
a0d0e21e 115
7e1af8bc 116# Fatal.pm needs to be fixed WRT prototypes.
117
118sub xfork {
119 my $pid = fork;
120 defined $pid or croak "$Me: fork failed: $!";
121 return $pid;
122}
123
124sub xpipe {
125 pipe $_[0], $_[1] or croak "$Me: pipe($_[0], $_[1]) failed: $!";
126}
127
128# I tried using a * prototype character for the filehandle but it still
129# disallows a bearword while compiling under strict subs.
a0d0e21e 130
7e1af8bc 131sub xopen {
132 open $_[0], $_[1] or croak "$Me: open($_[0], $_[1]) failed: $!";
133}
134
135sub xclose {
136 close $_[0] or croak "$Me: close($_[0]) failed: $!";
137}
138
f55ee38a 139my $do_spawn = $^O eq 'os2' || $^O eq 'MSWin32';
a24d8dfd 140
7e1af8bc 141sub _open3 {
142 local $Me = shift;
143 my($package, $dad_wtr, $dad_rdr, $dad_err, @cmd) = @_;
144 my($dup_wtr, $dup_rdr, $dup_err, $kidpid);
145
2675ae2b 146 # simulate autovivification of filehandles because
147 # it's too ugly to use @_ throughout to make perl do it for us
148 # tchrist 5-Mar-00
149
150 unless (eval {
151 $dad_wtr = $_[1] = gensym unless defined $dad_wtr && length $dad_wtr;
152 $dad_rdr = $_[2] = gensym unless defined $dad_rdr && length $dad_rdr;
153 1; })
154 {
155 # must strip crud for croak to add back, or looks ugly
156 $@ =~ s/(?<=value attempted) at .*//s;
157 croak "$Me: $@";
158 }
159
160 $dad_err ||= $dad_rdr;
a0d0e21e 161
4633a7c4 162 $dup_wtr = ($dad_wtr =~ s/^[<>]&//);
163 $dup_rdr = ($dad_rdr =~ s/^[<>]&//);
164 $dup_err = ($dad_err =~ s/^[<>]&//);
a0d0e21e 165
2675ae2b 166 # force unqualified filehandles into caller's package
7e1af8bc 167 $dad_wtr = qualify $dad_wtr, $package;
168 $dad_rdr = qualify $dad_rdr, $package;
169 $dad_err = qualify $dad_err, $package;
170
8b3e92c6 171 my $kid_rdr = gensym;
172 my $kid_wtr = gensym;
173 my $kid_err = gensym;
7e1af8bc 174
175 xpipe $kid_rdr, $dad_wtr if !$dup_wtr;
176 xpipe $dad_rdr, $kid_wtr if !$dup_rdr;
177 xpipe $dad_err, $kid_err if !$dup_err && $dad_err ne $dad_rdr;
178
a24d8dfd 179 $kidpid = $do_spawn ? -1 : xfork;
180 if ($kidpid == 0) { # Kid
7e1af8bc 181 # If she wants to dup the kid's stderr onto her stdout I need to
182 # save a copy of her stdout before I put something else there.
183 if ($dad_rdr ne $dad_err && $dup_err
184 && fileno($dad_err) == fileno(STDOUT)) {
8b3e92c6 185 my $tmp = gensym;
7e1af8bc 186 xopen($tmp, ">&$dad_err");
187 $dad_err = $tmp;
188 }
a0d0e21e 189
a0d0e21e 190 if ($dup_wtr) {
8ebc5c01 191 xopen \*STDIN, "<&$dad_wtr" if fileno(STDIN) != fileno($dad_wtr);
a0d0e21e 192 } else {
8ebc5c01 193 xclose $dad_wtr;
8b3e92c6 194 xopen \*STDIN, "<&=" . fileno $kid_rdr;
a0d0e21e 195 }
196 if ($dup_rdr) {
8ebc5c01 197 xopen \*STDOUT, ">&$dad_rdr" if fileno(STDOUT) != fileno($dad_rdr);
a0d0e21e 198 } else {
8ebc5c01 199 xclose $dad_rdr;
8b3e92c6 200 xopen \*STDOUT, ">&=" . fileno $kid_wtr;
a0d0e21e 201 }
202 if ($dad_rdr ne $dad_err) {
203 if ($dup_err) {
8b3e92c6 204 # I have to use a fileno here because in this one case
205 # I'm doing a dup but the filehandle might be a reference
206 # (from the special case above).
207 xopen \*STDERR, ">&" . fileno $dad_err
8ebc5c01 208 if fileno(STDERR) != fileno($dad_err);
a0d0e21e 209 } else {
8ebc5c01 210 xclose $dad_err;
8b3e92c6 211 xopen \*STDERR, ">&=" . fileno $kid_err;
a0d0e21e 212 }
213 } else {
8ebc5c01 214 xopen \*STDERR, ">&STDOUT" if fileno(STDERR) != fileno(STDOUT);
a0d0e21e 215 }
216 local($")=(" ");
2675ae2b 217 exec @cmd # XXX: wrong process to croak from
ad973f30 218 or croak "$Me: exec of @cmd failed";
a24d8dfd 219 } elsif ($do_spawn) {
220 # All the bookkeeping of coincidence between handles is
221 # handled in spawn_with_handles.
222
223 my @close;
224 if ($dup_wtr) {
8b3e92c6 225 $kid_rdr = \*{$dad_wtr};
226 push @close, $kid_rdr;
a24d8dfd 227 } else {
8b3e92c6 228 push @close, \*{$dad_wtr}, $kid_rdr;
a24d8dfd 229 }
230 if ($dup_rdr) {
8b3e92c6 231 $kid_wtr = \*{$dad_rdr};
232 push @close, $kid_wtr;
a24d8dfd 233 } else {
8b3e92c6 234 push @close, \*{$dad_rdr}, $kid_wtr;
a24d8dfd 235 }
236 if ($dad_rdr ne $dad_err) {
237 if ($dup_err) {
8b3e92c6 238 $kid_err = \*{$dad_err};
239 push @close, $kid_err;
a24d8dfd 240 } else {
8b3e92c6 241 push @close, \*{$dad_err}, $kid_err;
a24d8dfd 242 }
243 } else {
244 $kid_err = $kid_wtr;
245 }
246 require IO::Pipe;
247 $kidpid = eval {
248 spawn_with_handles( [ { mode => 'r',
8b3e92c6 249 open_as => $kid_rdr,
a24d8dfd 250 handle => \*STDIN },
251 { mode => 'w',
8b3e92c6 252 open_as => $kid_wtr,
a24d8dfd 253 handle => \*STDOUT },
254 { mode => 'w',
8b3e92c6 255 open_as => $kid_err,
a24d8dfd 256 handle => \*STDERR },
257 ], \@close, @cmd);
258 };
ad973f30 259 die "$Me: $@" if $@;
a0d0e21e 260 }
261
7e1af8bc 262 xclose $kid_rdr if !$dup_wtr;
263 xclose $kid_wtr if !$dup_rdr;
264 xclose $kid_err if !$dup_err && $dad_rdr ne $dad_err;
265 # If the write handle is a dup give it away entirely, close my copy
266 # of it.
267 xclose $dad_wtr if $dup_wtr;
a0d0e21e 268
269 select((select($dad_wtr), $| = 1)[0]); # unbuffer pipe
270 $kidpid;
271}
7e1af8bc 272
273sub open3 {
a24d8dfd 274 if (@_ < 4) {
275 local $" = ', ';
276 croak "open3(@_): not enough arguments";
277 }
7e1af8bc 278 return _open3 'open3', scalar caller, @_
279}
a0d0e21e 280
a24d8dfd 281sub spawn_with_handles {
282 my $fds = shift; # Fields: handle, mode, open_as
283 my $close_in_child = shift;
284 my ($fd, $pid, @saved_fh, $saved, %saved, @errs);
285 require Fcntl;
286
287 foreach $fd (@$fds) {
288 $fd->{tmp_copy} = IO::Handle->new_from_fd($fd->{handle}, $fd->{mode});
289 $saved{fileno $fd->{handle}} = $fd->{tmp_copy};
290 }
291 foreach $fd (@$fds) {
292 bless $fd->{handle}, 'IO::Handle'
293 unless eval { $fd->{handle}->isa('IO::Handle') } ;
294 # If some of handles to redirect-to coincide with handles to
295 # redirect, we need to use saved variants:
296 $fd->{handle}->fdopen($saved{fileno $fd->{open_as}} || $fd->{open_as},
297 $fd->{mode});
298 }
f55ee38a 299 unless ($^O eq 'MSWin32') {
300 # Stderr may be redirected below, so we save the err text:
301 foreach $fd (@$close_in_child) {
302 fcntl($fd, Fcntl::F_SETFD(), 1) or push @errs, "fcntl $fd: $!"
303 unless $saved{fileno $fd}; # Do not close what we redirect!
304 }
a24d8dfd 305 }
306
307 unless (@errs) {
308 $pid = eval { system 1, @_ }; # 1 == P_NOWAIT
309 push @errs, "IO::Pipe: Can't spawn-NOWAIT: $!" if !$pid || $pid < 0;
310 }
311
312 foreach $fd (@$fds) {
313 $fd->{handle}->fdopen($fd->{tmp_copy}, $fd->{mode});
314 $fd->{tmp_copy}->close or croak "Can't close: $!";
315 }
316 croak join "\n", @errs if @errs;
317 return $pid;
318}
319
3201; # so require is happy