diff options
author | Siep Kroonenberg <siepo@cybercomm.nl> | 2021-03-03 11:04:20 +0000 |
---|---|---|
committer | Siep Kroonenberg <siepo@cybercomm.nl> | 2021-03-03 11:04:20 +0000 |
commit | 13c3572d26e0868b9665513e4646ade860ae7810 (patch) | |
tree | 72f68d7c1270cc0a1d504f8eeb45d4de6b36f2d1 /Master/tlpkg/tlperl/lib/IPC | |
parent | 87d16a01498a53c4bb455d78ae7131370e47591e (diff) |
Updated tlperl
git-svn-id: svn://tug.org/texlive/trunk@58075 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg/tlperl/lib/IPC')
-rw-r--r-- | Master/tlpkg/tlperl/lib/IPC/Cmd.pm | 4 | ||||
-rw-r--r-- | Master/tlpkg/tlperl/lib/IPC/Open2.pm | 46 | ||||
-rw-r--r-- | Master/tlpkg/tlperl/lib/IPC/Open3.pm | 69 |
3 files changed, 67 insertions, 52 deletions
diff --git a/Master/tlpkg/tlperl/lib/IPC/Cmd.pm b/Master/tlpkg/tlperl/lib/IPC/Cmd.pm index 42cdd5990cb..88ed2955a9d 100644 --- a/Master/tlpkg/tlperl/lib/IPC/Cmd.pm +++ b/Master/tlpkg/tlperl/lib/IPC/Cmd.pm @@ -19,7 +19,7 @@ BEGIN { $HAVE_MONOTONIC ]; - $VERSION = '1.02'; + $VERSION = '1.04'; $VERBOSE = 0; $DEBUG = 0; $WARN = 1; @@ -1204,7 +1204,7 @@ sub run_forked { # which do setsid theirselves -- can't do anything # with those) - POSIX::setsid() || Carp::confess("Error running setsid: " . $!); + POSIX::setsid() == -1 and Carp::confess("Error running setsid: " . $!); if ($opts->{'child_BEGIN'} && ref($opts->{'child_BEGIN'}) eq 'CODE') { $opts->{'child_BEGIN'}->(); diff --git a/Master/tlpkg/tlperl/lib/IPC/Open2.pm b/Master/tlpkg/tlperl/lib/IPC/Open2.pm index 9e27144571d..cd330507990 100644 --- a/Master/tlpkg/tlperl/lib/IPC/Open2.pm +++ b/Master/tlpkg/tlperl/lib/IPC/Open2.pm @@ -6,7 +6,7 @@ our ($VERSION, @ISA, @EXPORT); require 5.000; require Exporter; -$VERSION = 1.04; +$VERSION = 1.05; @ISA = qw(Exporter); @EXPORT = qw(open2); @@ -18,38 +18,42 @@ IPC::Open2 - open a process for both reading and writing using open2() use IPC::Open2; - $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some cmd and args'); - # or without using the shell - $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some', 'cmd', 'and', 'args'); + my $pid = open2(my $chld_out, my $chld_in, + 'some', 'cmd', 'and', 'args'); + # or passing the command through the shell + my $pid = open2(my $chld_out, my $chld_in, 'some cmd and args'); - # or with handle autovivification - my($chld_out, $chld_in); - $pid = open2($chld_out, $chld_in, 'some cmd and args'); - # or without using the shell - $pid = open2($chld_out, $chld_in, 'some', 'cmd', 'and', 'args'); + # read from parent STDIN and write to already open handle + open my $outfile, '>', 'outfile.txt' or die "open failed: $!"; + my $pid = open2($outfile, '<&STDIN', 'some', 'cmd', 'and', 'args'); + # read from already open handle and write to parent STDOUT + open my $infile, '<', 'infile.txt' or die "open failed: $!"; + my $pid = open2('>&STDOUT', $infile, 'some', 'cmd', 'and', 'args'); + + # reap zombie and retrieve exit status waitpid( $pid, 0 ); my $child_exit_status = $? >> 8; =head1 DESCRIPTION -The open2() function runs the given $cmd and connects $chld_out for +The open2() function runs the given command and connects $chld_out for reading and $chld_in for writing. It's what you think should work when you try - $pid = open(HANDLE, "|cmd args|"); + my $pid = open(my $fh, "|cmd args|"); -The write filehandle will have autoflush turned on. +The $chld_in filehandle will have autoflush turned on. If $chld_out is a string (that is, a bareword filehandle rather than a glob or a reference) and it begins with C<< >& >>, then the child will send output directly to that file handle. If $chld_in is a string that begins with C<< <& >>, then $chld_in will be closed in the parent, and the child will -read from it directly. In both cases, there will be a dup(2) instead of a -pipe(2) made. +read from it directly. In both cases, there will be a L<dup(2)> instead of a +L<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 +If either reader or writer is the empty string or undefined, this will be +replaced by an autogenerated filehandle. If so, you must pass a valid lvalue in the parameter slot so it can be overwritten in the caller, or an exception will be raised. @@ -66,10 +70,10 @@ Failing to do this can result in an accumulation of defunct or "zombie" processes. See L<perlfunc/waitpid> for more information. This whole affair is quite dangerous, as you may block forever. It -assumes it's going to talk to something like B<bc>, both writing +assumes it's going to talk to something like L<bc(1)>, both writing to it and reading from it. This is presumably safe because you -"know" that commands like B<bc> will read a line at a time and -output a line at a time. Programs like B<sort> that read their +"know" that commands like L<bc(1)> will read a line at a time and +output a line at a time. Programs like L<sort(1)> that read their entire input stream first, however, are quite apt to cause deadlock. The big problem with this approach is that if you don't have control @@ -77,8 +81,8 @@ 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<cat -v> and continually read and write a line from it. -The IO::Pty and Expect modules from CPAN can help with this, as they -provide a real tty (well, a pseudo-tty, actually), which gets you +The L<IO::Pty> and L<Expect> modules from CPAN can help with this, as +they provide a real tty (well, a pseudo-tty, actually), which gets you back to line buffering in the invoked command again. =head1 WARNING diff --git a/Master/tlpkg/tlperl/lib/IPC/Open3.pm b/Master/tlpkg/tlperl/lib/IPC/Open3.pm index e5924a30a65..ce39d78f1ea 100644 --- a/Master/tlpkg/tlperl/lib/IPC/Open3.pm +++ b/Master/tlpkg/tlperl/lib/IPC/Open3.pm @@ -9,7 +9,7 @@ require Exporter; use Carp; use Symbol qw(gensym qualify); -$VERSION = '1.20'; +$VERSION = '1.21'; @ISA = qw(Exporter); @EXPORT = qw(open3); @@ -19,37 +19,48 @@ IPC::Open3 - open a process for reading, writing, and error handling using open3 =head1 SYNOPSIS - $pid = open3(\*CHLD_IN, \*CHLD_OUT, \*CHLD_ERR, - 'some cmd and args', 'optarg', ...); + use Symbol 'gensym'; # vivify a separate handle for STDERR + my $pid = open3(my $chld_in, my $chld_out, my $chld_err = gensym, + 'some', 'cmd', 'and', 'args'); + # or pass the command through the shell + my $pid = open3(my $chld_in, my $chld_out, my $chld_err = gensym, + 'some cmd and args'); - my($wtr, $rdr, $err); - use Symbol 'gensym'; $err = gensym; - $pid = open3($wtr, $rdr, $err, - 'some cmd and args', 'optarg', ...); + # read from parent STDIN + # send STDOUT and STDERR to already open handle + open my $outfile, '>>', 'output.txt' or die "open failed: $!"; + my $pid = open3('<&STDIN', $outfile, undef, + 'some', 'cmd', 'and', 'args'); + # write to parent STDOUT and STDERR + my $pid = open3(my $chld_in, '>&STDOUT', '>&STDERR', + 'some', 'cmd', 'and', 'args'); + + # reap zombie and retrieve exit status waitpid( $pid, 0 ); my $child_exit_status = $? >> 8; =head1 DESCRIPTION -Extremely similar to open2(), open3() spawns the given $cmd and -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 (this means that an autovivified lexical -cannot be used for the STDERR filehandle, see SYNOPSIS). The CHLD_IN +Extremely similar to open2(), open3() spawns the given command and +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. This means that an autovivified lexical +cannot be used for the STDERR filehandle, but gensym from L<Symbol> can +be used to vivify a new glob reference, see L</SYNOPSIS>. 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 $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 L<dup(2)> +instead of a L<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 -in the parameter slot so it can be overwritten in the caller, or -an exception will be raised. +If either reader or writer is the empty string or undefined, this will +be replaced by an autogenerated filehandle. If so, you must pass a +valid lvalue in the parameter slot so it can be overwritten in the +caller, or an exception will be raised. The filehandles may also be integers, in which case they are understood as file descriptors. @@ -57,15 +68,15 @@ 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</^open3:/>. However, C<exec> failures in the child (such as no such file or permission denied), -are just reported to CHLD_ERR under Windows and OS/2, as it is not possible +are just reported to $chld_err under Windows and OS/2, as it is not possible to trap them. -If the child process dies for any reason, the next write to CHLD_IN is +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<open(FOO, "-|")> the child process will just be the forked Perl +C<open(my $fh, "-|")> the child process will just be the forked Perl process rather than an external command. This feature isn't yet supported on Win32 platforms. @@ -78,14 +89,14 @@ processes. See L<perlfunc/waitpid> for more information. If you try to read from the child's stdout writer and their stderr writer, you'll have problems with blocking, which means you'll want -to use select() or the IO::Select, which means you'd best use +to use select() or L<IO::Select>, which means you'd best use sysread() instead of readline() for normal stuff. This is very dangerous, as you may block forever. It assumes it's -going to talk to something like B<bc>, both writing to it and reading +going to talk to something like L<bc(1)>, both writing to it and reading from it. This is presumably safe because you "know" that commands -like B<bc> will read a line at a time and output a line at a time. -Programs like B<sort> that read their entire input stream first, +like L<bc(1)> will read a line at a time and output a line at a time. +Programs like L<sort(1)> that read their entire input stream first, however, are quite apt to cause deadlock. The big problem with this approach is that if you don't have control |