The layers are returned in the order an open() or binmode() call would
use them. Note that the stack begins (normally) from C<stdio> or from
C<perlio>. Under C<stdio> the platform specific low-level I/O (like
-C<unix>) is not part of the stack, but under C<perlio> it is.
+C<unix>) is not part of the stack, but under C<perlio> (and the
+experimental C<mmap>) it is.
+
+In platforms of DOS progeny (Win32 being the most prominent) the
+lowest level layers are C<unix crlf>, meaning that Perl first uses the
+UNIX-style low-level fd layer, and then on top of that a layer that
+handles the CRLF translation.
+
+The following table summarizes the default layers on UNIX-like and
+DOS-like platforms and depending on the setting of the C<$ENV{PERLIO}>:
+
+ PERLIO UNIX-like DOS-like
+
+ none stdio unix crlf
+ stdio stdio stdio
+ perlio unix perlio unix perlio
+ mmap unix mmap unix mmap
By default the layers from the input side of the filehandle is
returned, to get the output side use the optional C<output> argument:
use Config;
+my $DOSISH = $^O =~ /^(?:MSWin32|cygwin|os2|dos|NetWare|mint)$/;
my $NONSTDIO = exists $ENV{PERLIO} && $ENV{PERLIO} ne 'stdio';
SKIP: {
sub check {
my ($result, $expected, $id) = @_;
- my $n = scalar @$expected;
- is($n, scalar @$expected, "$id - layers = $n");
if ($NONSTDIO) {
- # Get rid of "unix" and similar OS-specific low lever layer.
- shift(@$result);
+ # Get rid of "unix".
+ shift @$result if $result->[0] eq "unix";
# Change expectations.
$expected->[0] = $ENV{PERLIO} if $expected->[0] eq "stdio";
+ } elsif ($DOSISH) {
+ splice(@$result, 0, 2, "stdio")
+ if $result->[0] eq "unix" &&
+ $result->[1] eq "crlf";
}
+ my $n = scalar @$expected;
+ is($n, scalar @$expected, "$id - layers = $n");
for (my $i = 0; $i < $n; $i++) {
my $j = $expected->[$i];
if (ref $j eq 'CODE') {
[ "stdio" ],
":raw");
+ binmode(F, ":pop") if $DOSISH; # Drop one extra :crlf.
binmode(F, ":utf8");
check([ PerlIO::get_layers(F) ],
binmode(F, ":raw :encoding(latin1)"); # "latin1" will be canonized
- {
+ SKIP: {
+ skip("too complex layer coreography", 7) if $DOSISH;
+
my @results = PerlIO::get_layers(F, details => 1);
- # Get rid of "unix" and undef.
- splice(@results, 0, 2) if $NONSTDIO;
+ # Get rid of the args and the flags.
+ splice(@results, 1, 2) if $NONSTDIO;
check([ @results ],
[ "stdio", undef, sub { $_[0] > 0 },