xref: /openbsd/gnu/usr.bin/perl/t/io/through.t (revision 5af055cd)
1#!./perl
2
3BEGIN {
4    chdir 't' if -d 't';
5    @INC = '../lib';
6    require './test.pl';
7    skip_all("VMS too picky about line endings for record-oriented pipes")
8	if $^O eq 'VMS';
9}
10
11use strict;
12
13my $Perl = which_perl();
14
15my $data = <<'EOD';
16x
17 yy
18z
19EOD
20
21(my $data2 = $data) =~ s/\n/\n\n/g;
22
23my $t1 = { data => $data,  write_c => [1,2,length $data],  read_c => [1,2,3,length $data]};
24my $t2 = { data => $data2, write_c => [1,2,length $data2], read_c => [1,2,3,length $data2]};
25
26$_->{write_c} = [1..length($_->{data})],
27  $_->{read_c} = [1..length($_->{data})+1, 0xe000]  # Need <0xffff for REx
28    for (); # $t1, $t2;
29
30my $c;	# len write tests, for each: one _all test, and 3 each len+2
31$c += @{$_->{write_c}} * (1 + 3*@{$_->{read_c}}) for $t1, $t2;
32$c *= 3*2*2;	# $how_w, file/pipe, 2 reports
33
34$c += 6;	# Tests with sleep()...
35
36print "1..$c\n";
37
38my $set_out = '';
39$set_out = "binmode STDOUT, ':crlf'"
40    if defined  $main::use_crlf && $main::use_crlf == 1;
41
42sub testread ($$$$$$$) {
43  my ($fh, $str, $read_c, $how_r, $write_c, $how_w, $why) = @_;
44  my $buf = '';
45  if ($how_r eq 'readline_all') {
46    $buf .= $_ while <$fh>;
47  } elsif ($how_r eq 'readline') {
48    $/ = \$read_c;
49    $buf .= $_ while <$fh>;
50  } elsif ($how_r eq 'read') {
51    my($in, $c);
52    $buf .= $in while $c = read($fh, $in, $read_c);
53  } elsif ($how_r eq 'sysread') {
54    my($in, $c);
55    $buf .= $in while $c = sysread($fh, $in, $read_c);
56  } else {
57    die "Unrecognized read: '$how_r'";
58  }
59  close $fh or die "close: $!";
60  # The only contamination allowed is with sysread/prints
61  $buf =~ s/\r\n/\n/g if $how_r eq 'sysread' and $how_w =~ /print/;
62  is(length $buf, length $str, "length with wrc=$write_c, rdc=$read_c, $how_w, $how_r, $why");
63  is($buf, $str, "content with wrc=$write_c, rdc=$read_c, $how_w, $how_r, $why");
64}
65
66sub testpipe ($$$$$$) {
67  my ($str, $write_c, $read_c, $how_w, $how_r, $why) = @_;
68  (my $quoted = $str) =~ s/\n/\\n/g;;
69  my $fh;
70  if ($how_w eq 'print') {	# AUTOFLUSH???
71    # Should be shell-neutral:
72    open $fh, '-|', qq[$Perl -we "$set_out;print for grep length, split /(.{1,$write_c})/s, qq($quoted)"] or die "open: $!";
73  } elsif ($how_w eq 'print/flush') {
74    # shell-neutral and miniperl-enabled autoflush? qq(\x24\x7c) eq '$|'
75    open $fh, '-|', qq[$Perl -we "$set_out;eval qq(\\x24\\x7c = 1) or die;print for grep length, split /(.{1,$write_c})/s, qq($quoted)"] or die "open: $!";
76  } elsif ($how_w eq 'syswrite') {
77    ### How to protect \$_
78    open $fh, '-|', qq[$Perl -we "$set_out;eval qq(sub w {syswrite STDOUT, \\x24_} 1) or die; w() for grep length, split /(.{1,$write_c})/s, qq($quoted)"] or die "open: $!";
79  } else {
80    die "Unrecognized write: '$how_w'";
81  }
82  binmode $fh, ':crlf'
83      if defined $main::use_crlf && $main::use_crlf == 1;
84  testread($fh, $str, $read_c, $how_r, $write_c, $how_w, "pipe$why");
85}
86
87sub testfile ($$$$$$) {
88  my ($str, $write_c, $read_c, $how_w, $how_r, $why) = @_;
89  my @data = grep length, split /(.{1,$write_c})/s, $str;
90
91  my $filename = tempfile();
92  open my $fh, '>', $filename or die;
93  select $fh;
94  binmode $fh, ':crlf'
95      if defined $main::use_crlf && $main::use_crlf == 1;
96  if ($how_w eq 'print') {	# AUTOFLUSH???
97    $| = 0;
98    print $fh $_ for @data;
99  } elsif ($how_w eq 'print/flush') {
100    $| = 1;
101    print $fh $_ for @data;
102  } elsif ($how_w eq 'syswrite') {
103    syswrite $fh, $_ for @data;
104  } else {
105    die "Unrecognized write: '$how_w'";
106  }
107  close $fh or die "close: $!";
108  open $fh, '<', $filename or die;
109  binmode $fh, ':crlf'
110      if defined $main::use_crlf && $main::use_crlf == 1;
111  testread($fh, $str, $read_c, $how_r, $write_c, $how_w, "file$why");
112}
113
114# shell-neutral and miniperl-enabled autoflush? qq(\x24\x7c) eq '$|'
115open my $fh, '-|', qq[$Perl -we "eval qq(\\x24\\x7c = 1) or die; binmode STDOUT; sleep 1, print for split //, qq(a\nb\n\nc\n\n\n)"] or die "open: $!";
116ok(1, 'open pipe');
117binmode $fh, q(:crlf);
118ok(1, 'binmode');
119$c = undef;
120my @c;
121push @c, ord $c while $c = getc $fh;
122ok(1, 'got chars');
123is(scalar @c, 9, 'got 9 chars');
124is("@c", '97 10 98 10 10 99 10 10 10', 'got expected chars');
125ok(close($fh), 'close');
126
127for my $s (1..2) {
128  my $t = ($t1, $t2)[$s-1];
129  my $str = $t->{data};
130  my $r = $t->{read_c};
131  my $w = $t->{write_c};
132  for my $read_c (@$r) {
133    for my $write_c (@$w) {
134      for my $how_r (qw(readline_all readline read sysread)) {
135	next if $how_r eq 'readline_all' and $read_c != 1;
136        for my $how_w (qw(print print/flush syswrite)) {
137	  testfile($str, $write_c, $read_c, $how_w, $how_r, $s);
138	  testpipe($str, $write_c, $read_c, $how_w, $how_r, $s);
139        }
140      }
141    }
142  }
143}
144
1451;
146