cpan-authors / IPC-Run

https://metacpan.org/pod/IPC::Run
Other
21 stars 38 forks source link

IPC::Run converts '\t' to spaces #170

Closed japinli closed 10 months ago

japinli commented 10 months ago

Hi, all

When I try to run PostgreSQL regression test on Illumos, I encounterd a problem with IPC::Run:pump() functions, which convert '\t' to 8 spaces. Here is a simple example.

[japin@db_build ~/perl-test]$ cat test.pl
use IPC::Run qw( start pump finish timeout );
eval { require IO::Pty; };
if ($@) {
  die "could not load IO::Pty";
}

my @cat = qw( cat );

my $h = start \@cat, '<pty<', \$in, '>pty>', \$out, '2>', \$err, timeout(4);

$in .= "SEL\tH";
pump $h until $out =~ /SEL/g;
print $out;

[japin@db_build ~/perl-test]$ perl test.pl > t0.txt
[japin@db_build ~/perl-test]$ ls -l t0.txt
-rw-r--r-- 1 japin other 9 Nov  2 08:06 t0.txt

I try to write 'SEL\tH', but got 'SEL H' (with 5 spaces), I'm expected the output is 'SEL H' (with 1 tab character).

Here is my environment:

[japin@db_build ~/perl-test]$ perl --version

This is perl 5, version 34, subversion 0 (v5.34.0) built for x86_64-solaris-thread-multi-64

Copyright 1987-2021, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

[japin@db_build ~/perl-test]$ uname -a
SunOS db_build 5.11 hunghu-20231030T232939Z:1214af5d73 i86pc i386 i86pc illumos

Here is the debug information:

[japin@db_build ~/perl-test]$ IPCRUNDEBUG=all perl test.pl > t0.txt
IPC::Run 0000 012--------- [(470645)]: timer #1 interval set to 4
IPC::Run 0000 012--------- [(470645)]: timer #1 constructed
IPC::Run 0000 012--------- [(470645)]: timer #1 exception set to IPC::Run: timeout on timer #1
IPC::Run 0000 0123-------- [#1(470645)]: debugging fd is 3
IPC::Run 0000 0123-------- [#1(470645)]: ****** harnessing *****
IPC::Run 0000 0123-------- [#1(470645)]: parsing [ 'cat' ]
IPC::Run 0000 0123-------- [#1(470645)]: parsing '<pty<'
IPC::Run 0000 0123-------- [#1(470645)]: parsing '>pty>'
IPC::Run 0000 0123-------- [#1(470645)]: parsing '2>'
IPC::Run 0000 0123-------- [#1(470645)]: parsing IPC::Run::Timer
IPC::Run 0000 0123-------- [#1(470645)]: ** starting
IPC::Run 0000 0123-------- [#1(470645)]: timer #1 state set to 1
IPC::Run 0000 0123-------- [#1(470645)]: timer #1 start_time set to 1698912974
IPC::Run 0000 0123-------- [#1(470645)]: timer #1 end_time set to 1698912979
IPC::Run 0000 0123-------- [#1(470645)]: timer #1 started at 1698912974, with interval 4, end_time 1698912979
IPC::Run 0000 0123-------- [#1(470645)]: opening pty '0'
IPC::Run 0001 0123456----- [#1(470645)]: pty() = ( 4, 6 )
IPC::Run 0001 0123456----- [#1(470645)]: 'cat' added to cache: '/opt/local/bin/cat'
IPC::Run 0001 0123456----- [#1(470645)]: kid to read 0 from pty '0'
IPC::Run 0001 0123456----- [#1(470645)]: kid 1 to read 0 from SCALAR via pty '0'
IPC::Run 0001 0123456----- [#1(470645)]: kid 1 to write 1 to SCALAR via pty '0'
IPC::Run 0001 0123456----- [#1(470645)]: kid 1 to write 2 to SCALAR
IPC::Run 0001 012345678--- [#1(470645)]: pipe() = ( 7, 8 )
IPC::Run 0001 012345678--- [#1(470645)]: kid 1[]'s 0 is my 4
IPC::Run 0001 012345678--- [#1(470645)]: kid 1[]'s 1 is my 4
IPC::Run 0001 012345678--- [#1(470645)]: kid 1[]'s 2 is my 7
IPC::Run 0001 012345678--- [#1(470645)]: child: `cat`
IPC::Run 0001 012345678--- [#1(470645)]: opening sync pipe
IPC::Run 0001 01234567890- [#1(470645)]: pipe() = ( 9, 10 )
IPC::Run 0001 01234567890- [#1(470645)]: fork() = 470646
IPC::Run 0001 0123456789-- [#1(470645)]: close( 10 ) = 0
IPC::Run 0001 01234567890- [#1(470646) cat]: Cleaning up parent's ptty '0'
IPC::Run 0001 0123-567890- [#1(470646) cat]: closing stdin, out, err
IPC::Run 0001 ---3-567890- [#1(470646) cat]: open fds: 9 3 8 10 7 6
IPC::Run 0001 ---3-5678-0- [#1(470646) cat]: close( 9 ) = 0
IPC::Run 0001 ---3-56-8-0- [#1(470646) cat]: close( 7 ) = 0
IPC::Run 0001 0--3-56-8-0- [#1(470646) cat]: dup2( 6, 0 ) = 0
IPC::Run 0001 01-3-56-8-0- [#1(470646) cat]: dup2( 6, 1 ) = 1
IPC::Run 0001 0123-56-8-0- [#1(470646) cat]: dup2( 1, 2 ) = 2
IPC::Run 0001 0123-56-8-0- [#1(470646) cat]: dup2( 8, 2 ) = 2
IPC::Run 0001 0123-5--8-0- [#1(470646) cat]: close( 6 ) = 0
IPC::Run 0001 0123-5----0- [#1(470646) cat]: close( 8 ) = 0
IPC::Run 0001 0123-5----0- [#1(470646) cat]: execing /opt/local/bin/cat
IPC::Run 0001 0123-5----0- [#1(470646) cat]: exec()ing '/opt/local/bin/cat'
IPC::Run 0001 0123456789-- [#1(470645)]: read( 9 ) = 0 but true chars ''
IPC::Run 0001 012345678--- [#1(470645)]: close( 9 ) = 0
IPC::Run 0001 012345-7---- [#1(470645)]: close( 8 ) = 0
IPC::Run 0001 012345-7---- [#1(470645)]: ** pumping
IPC::Run 0001 012345-7---- [#1(470645)]: checking timer #1 (end time 1698912979) at 1698912975
IPC::Run 0001 012345-7---- [#1(470645)]: fds for select: ----b--r----
IPC::Run 0001 012345-7---- [#1(470645)]: timeout=0.01
IPC::Run 0001 012345-7---- [#1(470645)]: selected  ----w-------
IPC::Run 0001 012345-7---- [#1(470645)]: filtering data to fd 4 (kid's stdin)
IPC::Run 0001 012345-7---- [#1(470645)]: writing to fd 4 (kid's stdin)
IPC::Run 0001 012345-7---- [#1(470645)]: write( 4, 'SEL H' ) = 5
IPC::Run 0001 012345-7---- [#1(470645)]: exiting _select(): io occurred and break_on_io set
IPC::Run 0001 012345-7---- [#1(470645)]: ** pumping
IPC::Run 0001 012345-7---- [#1(470645)]: checking timer #1 (end time 1698912979) at 1698912975
IPC::Run 0001 012345-7---- [#1(470645)]: fds for select: ----b--r----
IPC::Run 0001 012345-7---- [#1(470645)]: timeout=0.01
IPC::Run 0001 012345-7---- [#1(470645)]: selected  ----b-------
IPC::Run 0001 012345-7---- [#1(470645)]: filtering data to fd 4 (kid's stdin)
IPC::Run 0001 012345-7---- [#1(470645)]: pausing fd 4 (kid's stdin)
IPC::Run 0001 012345-7---- [#1(470645)]: filtering data from fd 4 (kid's stdout)
IPC::Run 0001 012345-7---- [#1(470645)]: reading from fd 4 (kid's stdout)
IPC::Run 0001 012345-7---- [#1(470645)]: read( 4 ) = 9 chars 'SEL     H'
IPC::Run 0001 012345-7---- [#1(470645)]: exiting _select(): io occurred and break_on_io set

Then, I try to remove the IO::Pty, everything is ok.

[japin@db_build ~/perl-test]$ cat test.pl
use IPC::Run qw( start pump finish timeout );

my @cat = qw( cat );

my $h = start \@cat, \$in, \$out, \$err, timeout(4);

$in .= "SEL\tH";
pump $h until $out =~ /SEL/g;
print $out;

[japin@db_build ~/perl-test]$ perl test.pl > t1.txt
[japin@db_build ~/perl-test]$ ls -l t1.txt
-rw-r--r-- 1 japin other 5 Nov  2 08:21 t1.txt
japinli commented 10 months ago

After some analyze, I find this might be a bug comes for Illumos pseudo-tty. See: https://www.postgresql.org/message-id/MEYP282MB16690099A6A685119F871F07B6A6A%40MEYP282MB1669.AUSP282.PROD.OUTLOOK.COM

Sorry to the noise! Close the issue.