This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Avoid POSIX::close when closing files by descriptor in IPC::Open3
[perl5.git] / ext / IPC-Open3 / 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
8700fd38 12$VERSION = '1.13';
7e1af8bc 13@ISA = qw(Exporter);
14@EXPORT = qw(open3);
a0d0e21e 15
f06db76b
AD
16=head1 NAME
17
14333e50 18IPC::Open3 - open a process for reading, writing, and error handling using open3()
f06db76b
AD
19
20=head1 SYNOPSIS
21
3ce239a0 22 $pid = open3(\*CHLD_IN, \*CHLD_OUT, \*CHLD_ERR,
f06db76b
AD
23 'some cmd and args', 'optarg', ...);
24
2675ae2b 25 my($wtr, $rdr, $err);
92be7001 26 use Symbol 'gensym'; $err = gensym;
2675ae2b
GS
27 $pid = open3($wtr, $rdr, $err,
28 'some cmd and args', 'optarg', ...);
29
b2080196 30 waitpid( $pid, 0 );
31 my $child_exit_status = $? >> 8;
32
f06db76b
AD
33=head1 DESCRIPTION
34
35Extremely similar to open2(), open3() spawns the given $cmd and
3ce239a0
BT
36connects CHLD_OUT for reading from the child, CHLD_IN for writing to
37the child, and CHLD_ERR for errors. If CHLD_ERR is false, or the
38same file descriptor as CHLD_OUT, then STDOUT and STDERR of the child
92be7001
SR
39are on the same filehandle (this means that an autovivified lexical
40cannot be used for the STDERR filehandle, see SYNOPSIS). The CHLD_IN
41will have autoflush turned on.
3ce239a0
BT
42
43If CHLD_IN begins with C<< <& >>, then CHLD_IN will be closed in the
44parent, and the child will read from it directly. If CHLD_OUT or
45CHLD_ERR begins with C<< >& >>, then the child will send output
46directly to that filehandle. In both cases, there will be a dup(2)
47instead of a pipe(2) made.
f06db76b 48
2675ae2b
GS
49If either reader or writer is the null string, this will be replaced
50by an autogenerated filehandle. If so, you must pass a valid lvalue
8960aa87 51in the parameter slot so it can be overwritten in the caller, or
2675ae2b 52an exception will be raised.
cb1a09d0 53
036b4402
GS
54The filehandles may also be integers, in which case they are understood
55as file descriptors.
56
7e1af8bc 57open3() returns the process ID of the child process. It doesn't return on
2675ae2b 58failure: it just raises an exception matching C</^open3:/>. However,
eee4b3e7
DM
59C<exec> failures in the child (such as no such file or permission denied),
60are just reported to CHLD_ERR, as it is not possible to trap them.
61
62If the child process dies for any reason, the next write to CHLD_IN is
63likely to generate a SIGPIPE in the parent, which is fatal by default.
64So you may wish to handle this signal.
f06db76b 65
a2a63531
AS
66Note if you specify C<-> as the command, in an analogous fashion to
67C<open(FOO, "-|")> the child process will just be the forked Perl
68process rather than an external command. This feature isn't yet
69supported on Win32 platforms.
70
8960aa87 71open3() does not wait for and reap the child process after it exits.
227e8dd4 72Except for short programs where it's acceptable to let the operating system
8960aa87 73take care of this, you need to do this yourself. This is normally as
227e8dd4
GS
74simple as calling C<waitpid $pid, 0> when you're done with the process.
75Failing to do this can result in an accumulation of defunct or "zombie"
76processes. See L<perlfunc/waitpid> for more information.
77
2675ae2b
GS
78If you try to read from the child's stdout writer and their stderr
79writer, you'll have problems with blocking, which means you'll want
80to use select() or the IO::Select, which means you'd best use
81sysread() instead of readline() for normal stuff.
82
83This is very dangerous, as you may block forever. It assumes it's
84going to talk to something like B<bc>, both writing to it and reading
85from it. This is presumably safe because you "know" that commands
86like B<bc> will read a line at a time and output a line at a time.
87Programs like B<sort> that read their entire input stream first,
7e1af8bc 88however, are quite apt to cause deadlock.
89
90The big problem with this approach is that if you don't have control
7a2e2cd6 91over source code being run in the child process, you can't control
7e1af8bc 92what it does with pipe buffering. Thus you can't just open a pipe to
93C<cat -v> and continually read and write a line from it.
94
eee4b3e7
DM
95=head1 See Also
96
97=over 4
98
99=item L<IPC::Open2>
100
101Like Open3 but without STDERR catpure.
102
103=item L<IPC::Run>
104
105This is a CPAN module that has better error handling and more facilities
106than Open3.
107
108=back
109
2675ae2b
GS
110=head1 WARNING
111
112The order of arguments differs from that of open2().
113
7e1af8bc 114=cut
a0d0e21e
LW
115
116# &open3: Marc Horowitz <marc@mit.edu>
117# derived mostly from &open2 by tom christiansen, <tchrist@convex.com>
4633a7c4 118# fixed for 5.001 by Ulrich Kunitz <kunitz@mai-koeln.com>
f55ee38a 119# ported to Win32 by Ron Schmidt, Merrill Lynch almost ended my career
2675ae2b 120# fixed for autovivving FHs, tchrist again
6662521e 121# allow fd numbers to be used, by Frank Tobin
a2a63531 122# allow '-' as command (c.f. open "-|"), by Adam Spiers <perl@adamspiers.org>
a0d0e21e 123#
a0d0e21e
LW
124# usage: $pid = open3('wtr', 'rdr', 'err' 'some cmd and args', 'optarg', ...);
125#
126# spawn the given $cmd and connect rdr for
127# reading, wtr for writing, and err for errors.
128# if err is '', or the same as rdr, then stdout and
129# stderr of the child are on the same fh. returns pid
7e1af8bc 130# of child (or dies on failure).
a0d0e21e
LW
131
132
4633a7c4 133# if wtr begins with '<&', then wtr will be closed in the parent, and
a0d0e21e
LW
134# the child will read from it directly. if rdr or err begins with
135# '>&', then the child will send output directly to that fd. In both
136# cases, there will be a dup() instead of a pipe() made.
137
138
139# WARNING: this is dangerous, as you may block forever
140# unless you are very careful.
141#
142# $wtr is left unbuffered.
143#
144# abort program if
145# rdr or wtr are null
7e1af8bc 146# a system call fails
a0d0e21e 147
2675ae2b 148our $Me = 'open3 (bug)'; # you should never see this, it's always localized
a0d0e21e 149
7e1af8bc 150# Fatal.pm needs to be fixed WRT prototypes.
151
7e1af8bc 152sub xpipe {
153 pipe $_[0], $_[1] or croak "$Me: pipe($_[0], $_[1]) failed: $!";
154}
155
156# I tried using a * prototype character for the filehandle but it still
b7b1e41b 157# disallows a bareword while compiling under strict subs.
a0d0e21e 158
7e1af8bc 159sub xopen {
ea87ae30
NC
160 open $_[0], $_[1], @_[2..$#_] and return;
161 local $" = ', ';
162 carp "$Me: open(@_) failed: $!";
7e1af8bc 163}
164
165sub xclose {
8700fd38
SH
166 $_[0] =~ /\A=?(\d+)\z/
167 ? do { my $fh; open($fh, $_[1] . '&=' . $1) and close($fh); }
168 : close $_[0]
f6f8630d 169 or croak "$Me: close($_[0]) failed: $!";
7e1af8bc 170}
171
036b4402
GS
172sub xfileno {
173 return $1 if $_[0] =~ /\A=?(\d+)\z/; # deal with fh just being an fd
174 return fileno $_[0];
6662521e
GS
175}
176
f598f6de
NC
177use constant FORCE_DEBUG_SPAWN => 0;
178use constant DO_SPAWN => $^O eq 'os2' || $^O eq 'MSWin32' || FORCE_DEBUG_SPAWN;
a24d8dfd 179
7e1af8bc 180sub _open3 {
181 local $Me = shift;
eee4b3e7 182
2675ae2b
GS
183 # simulate autovivification of filehandles because
184 # it's too ugly to use @_ throughout to make perl do it for us
185 # tchrist 5-Mar-00
186
187 unless (eval {
cf0c26e1
NC
188 $_[0] = gensym unless defined $_[0] && length $_[0];
189 $_[1] = gensym unless defined $_[1] && length $_[1];
8960aa87 190 1; })
2675ae2b
GS
191 {
192 # must strip crud for croak to add back, or looks ugly
193 $@ =~ s/(?<=value attempted) at .*//s;
194 croak "$Me: $@";
8960aa87 195 }
2675ae2b 196
cae0d269
NC
197 my @handles = ({ mode => '<', handle => \*STDIN },
198 { mode => '>', handle => \*STDOUT },
199 { mode => '>', handle => \*STDERR },
b74a613e
NC
200 );
201
9340a1e0
NC
202 foreach (@handles) {
203 $_->{parent} = shift;
b38d735f 204 $_->{open_as} = gensym;
9340a1e0
NC
205 }
206
9340a1e0 207 if (@_ > 1 and $_[0] eq '-') {
cf0c26e1
NC
208 croak "Arguments don't make sense when the command is '-'"
209 }
210
9340a1e0 211 $handles[2]{parent} ||= $handles[1]{parent};
f2412f89 212 $handles[2]{dup_of_out} = $handles[1]{parent} eq $handles[2]{parent};
a0d0e21e 213
0c12e47a
NC
214 my $package;
215 foreach (@handles) {
216 $_->{dup} = ($_->{parent} =~ s/^[<>]&//);
a0d0e21e 217
0c12e47a
NC
218 if ($_->{parent} !~ /\A=?(\d+)\z/) {
219 # force unqualified filehandles into caller's package
220 $package //= caller 1;
221 $_->{parent} = qualify $_->{parent}, $package;
222 }
7e1af8bc 223
0c12e47a
NC
224 next if $_->{dup} or $_->{dup_of_out};
225 if ($_->{mode} eq '<') {
226 xpipe $_->{open_as}, $_->{parent};
227 } else {
228 xpipe $_->{parent}, $_->{open_as};
229 }
230 }
7e1af8bc 231
38e62fca 232 my $kidpid;
8960aa87
EB
233 if (!DO_SPAWN) {
234 # Used to communicate exec failures.
235 xpipe my $stat_r, my $stat_w;
236
258a5898
NC
237 $kidpid = fork;
238 croak "$Me: fork failed: $!" unless defined $kidpid;
8960aa87
EB
239 if ($kidpid == 0) { # Kid
240 eval {
241 # A tie in the parent should not be allowed to cause problems.
242 untie *STDIN;
243 untie *STDOUT;
244
245 close $stat_r;
258a5898
NC
246 require Fcntl;
247 my $flags = fcntl $stat_w, &Fcntl::F_GETFD, 0;
248 croak "$Me: fcntl failed: $!" unless $flags;
249 fcntl $stat_w, &Fcntl::F_SETFD, $flags|&Fcntl::FD_CLOEXEC
250 or croak "$Me: fcntl failed: $!";
8960aa87
EB
251
252 # If she wants to dup the kid's stderr onto her stdout I need to
253 # save a copy of her stdout before I put something else there.
f2412f89 254 if (!$handles[2]{dup_of_out} && $handles[2]{dup}
9340a1e0 255 && xfileno($handles[2]{parent}) == fileno \*STDOUT) {
8960aa87 256 my $tmp = gensym;
9340a1e0
NC
257 xopen($tmp, '>&', $handles[2]{parent});
258 $handles[2]{parent} = $tmp;
8960aa87
EB
259 }
260
afebf859
NC
261 foreach (@handles) {
262 if ($_->{dup_of_out}) {
263 xopen \*STDERR, ">&STDOUT"
264 if defined fileno STDERR && fileno STDERR != fileno STDOUT;
265 } elsif ($_->{dup}) {
266 xopen $_->{handle}, $_->{mode} . '&', $_->{parent}
267 if fileno $_->{handle} != xfileno($_->{parent});
8960aa87 268 } else {
8700fd38 269 xclose $_->{parent}, $_->{mode};
afebf859
NC
270 xopen $_->{handle}, $_->{mode} . '&=',
271 fileno $_->{open_as};
8960aa87 272 }
8960aa87 273 }
f8b0429f 274 return 1 if ($_[0] eq '-');
9340a1e0 275 exec @_ or do {
8960aa87 276 local($")=(" ");
9340a1e0 277 croak "$Me: exec of @_ failed";
8960aa87 278 };
f8b0429f
SF
279 } and do {
280 close $stat_w;
281 return 0;
282 };
8960aa87
EB
283
284 my $bang = 0+$!;
285 my $err = $@;
286 utf8::encode $err if $] >= 5.008;
287 print $stat_w pack('IIa*', $bang, length($err), $err);
288 close $stat_w;
a0d0e21e 289
8960aa87
EB
290 eval { require POSIX; POSIX::_exit(255); };
291 exit 255;
a0d0e21e 292 }
8960aa87
EB
293 else { # Parent
294 close $stat_w;
295 my $to_read = length(pack('I', 0)) * 2;
296 my $bytes_read = read($stat_r, my $buf = '', $to_read);
297 if ($bytes_read) {
298 (my $bang, $to_read) = unpack('II', $buf);
299 read($stat_r, my $err = '', $to_read);
300 if ($err) {
301 utf8::decode $err if $] >= 5.008;
302 } else {
303 $err = "$Me: " . ($! = $bang);
304 }
305 $! = $bang;
306 die($err);
a0d0e21e 307 }
a0d0e21e 308 }
8960aa87
EB
309 }
310 else { # DO_SPAWN
a24d8dfd
IZ
311 # All the bookkeeping of coincidence between handles is
312 # handled in spawn_with_handles.
313
314 my @close;
a500d274
NC
315
316 foreach (@handles) {
317 if ($_->{dup_of_out}) {
318 $_->{open_as} = $handles[1]{open_as};
319 } elsif ($_->{dup}) {
320 $_->{open_as} = $_->{parent} =~ /\A[0-9]+\z/
321 ? $_->{parent} : \*{$_->{parent}};
322 push @close, $_->{open_as};
a24d8dfd 323 } else {
a500d274 324 push @close, \*{$_->{parent}}, $_->{open_as};
a24d8dfd 325 }
a24d8dfd
IZ
326 }
327 require IO::Pipe;
328 $kidpid = eval {
9340a1e0 329 spawn_with_handles(\@handles, \@close, @_);
a24d8dfd 330 };
ad973f30 331 die "$Me: $@" if $@;
a0d0e21e
LW
332 }
333
0c12e47a
NC
334 foreach (@handles) {
335 next if $_->{dup} or $_->{dup_of_out};
8700fd38 336 xclose $_->{open_as}, $_->{mode};
0c12e47a
NC
337 }
338
7e1af8bc 339 # If the write handle is a dup give it away entirely, close my copy
340 # of it.
8700fd38 341 xclose $handles[0]{parent}, $handles[0]{mode} if $handles[0]{dup};
a0d0e21e 342
9340a1e0 343 select((select($handles[0]{parent}), $| = 1)[0]); # unbuffer pipe
a0d0e21e
LW
344 $kidpid;
345}
7e1af8bc 346
347sub open3 {
a24d8dfd
IZ
348 if (@_ < 4) {
349 local $" = ', ';
350 croak "open3(@_): not enough arguments";
351 }
0689e260 352 return _open3 'open3', @_
7e1af8bc 353}
a0d0e21e 354
a24d8dfd
IZ
355sub spawn_with_handles {
356 my $fds = shift; # Fields: handle, mode, open_as
357 my $close_in_child = shift;
358 my ($fd, $pid, @saved_fh, $saved, %saved, @errs);
a24d8dfd
IZ
359
360 foreach $fd (@$fds) {
361 $fd->{tmp_copy} = IO::Handle->new_from_fd($fd->{handle}, $fd->{mode});
031f91ce 362 $saved{fileno $fd->{handle}} = $fd->{tmp_copy} if $fd->{tmp_copy};
a24d8dfd
IZ
363 }
364 foreach $fd (@$fds) {
365 bless $fd->{handle}, 'IO::Handle'
366 unless eval { $fd->{handle}->isa('IO::Handle') } ;
367 # If some of handles to redirect-to coincide with handles to
368 # redirect, we need to use saved variants:
b38d735f
NC
369 $fd->{handle}->fdopen(defined fileno $fd->{open_as}
370 ? $saved{fileno $fd->{open_as}} || $fd->{open_as}
371 : $fd->{open_as},
a24d8dfd
IZ
372 $fd->{mode});
373 }
f55ee38a 374 unless ($^O eq 'MSWin32') {
cae0d269 375 require Fcntl;
f55ee38a
GS
376 # Stderr may be redirected below, so we save the err text:
377 foreach $fd (@$close_in_child) {
f598f6de 378 next unless fileno $fd;
f55ee38a
GS
379 fcntl($fd, Fcntl::F_SETFD(), 1) or push @errs, "fcntl $fd: $!"
380 unless $saved{fileno $fd}; # Do not close what we redirect!
381 }
a24d8dfd
IZ
382 }
383
384 unless (@errs) {
f598f6de
NC
385 if (FORCE_DEBUG_SPAWN) {
386 pipe my $r, my $w or die "Pipe failed: $!";
387 $pid = fork;
388 die "Fork failed: $!" unless defined $pid;
389 if (!$pid) {
390 { no warnings; exec @_ }
391 print $w 0 + $!;
392 close $w;
393 require POSIX;
394 POSIX::_exit(255);
395 }
396 close $w;
397 my $bad = <$r>;
398 if (defined $bad) {
399 $! = $bad;
400 undef $pid;
401 }
402 } else {
403 $pid = eval { system 1, @_ }; # 1 == P_NOWAIT
404 }
a24d8dfd
IZ
405 push @errs, "IO::Pipe: Can't spawn-NOWAIT: $!" if !$pid || $pid < 0;
406 }
407
031f91ce
NC
408 # Do this in reverse, so that STDERR is restored first:
409 foreach $fd (reverse @$fds) {
a24d8dfd 410 $fd->{handle}->fdopen($fd->{tmp_copy}, $fd->{mode});
031f91ce
NC
411 }
412 foreach (values %saved) {
413 $_->close or croak "Can't close: $!";
a24d8dfd
IZ
414 }
415 croak join "\n", @errs if @errs;
416 return $pid;
417}
418
4191; # so require is happy