Sys-Binmode

 view release on metacpan or  search on metacpan

lib/Sys/Binmode.pm  view on Meta::CPAN

exposes multiple APIs for creating a directory, and the one Perl uses (as of
5.32, anyway) only accepts code points 0-255. In this context Sys::Binmode
doesn’t I<break> anything, but it does reinforce one of Perl’s unfortunate
limitations on Windows.

Sys::Binmode is a good idea anywhere that Perl sends byte strings to the OS.
For now, as far as I know, that’s everywhere that Perl runs. If that’s not
true, please file a bug.

=head1 WHERE ELSE THIS PROBLEM CAN APPEAR

The unpredictable-behavior problem that this module fixes in core Perl is
also common in L<CPAN|http://cpan.org>’s XS modules due to rampant
use of L<the SvPV macro|https://perldoc.perl.org/perlapi#SvPV> and
variants. SvPV is basically Perl’s L<bytes> pragma in C: it gives
you the string’s
internal bytes with no regard for what those bytes represent. This, of course,
is problematic for the same reason why the L<bytes> pragma is. XS authors
I<generally> should prefer
L<SvPVbyte|https://perldoc.perl.org/perlapi#SvPVbyte>
or L<SvPVutf8|https://perldoc.perl.org/perlapi#SvPVutf8> in lieu of
SvPV unless the C code in question handles Perl’s encoding abstraction.

Note in particular that, as of Perl 5.32, the default XS typemap converts
scalars to C C<char *> and C<const char *> via an SvPV variant. This means
that any module that uses that conversion logic also has this problem.
So XS authors should also avoid the default typemap for such conversions.
(Again, though, use of the default typemap in this context is regrettably
commonplace.)

Before Perl 5.18 this problem also affected %ENV. 5.18 introduced
an auto-downgrade when setting %ENV similar to what this module does.

=head1 LEXICAL SCOPING

If, for some reason, you I<want> Perl’s unpredictable default behavior,
you can disable this module for a given block via
C<no Sys::Binmode>, thus:

    use Sys::Binmode;

    system 'echo', $foo;        # predictable/sane/happy

    {

        # You should probably explain here why you’re doing this.
        no Sys::Binmode;

        system 'echo', $foo;    # nasal demons
    }

=head1 AFFECTED BUILT-INS

=over

=item * C<exec>, C<system>, and C<readpipe>

=item * C<do> and C<require>

=item * File tests (e.g., C<-e>) and the following:
C<chdir>, C<chmod>, C<chown>, C<chroot>, C<ioctl>,
C<link>, C<lstat>, C<mkdir>, C<open>, C<opendir>, C<readlink>, C<rename>,
C<rmdir>, C<stat>, C<symlink>, C<sysopen>, C<truncate>,
C<unlink>, C<utime>

=item * C<bind>, C<connect>, C<setsockopt>, and C<send> (last argument)

=item * C<syscall>

=back

=head2 Omissions

=over

=item * C<crypt> already does as Sys::Binmode would make it do.

=item * C<select> (the 4-argument one) has the bug that Sys::Binmode fixes,
but since it’s a performance-sensitive call where upgraded strings are
unlikely, this library doesn’t wrap it.

=back

=head1 KNOWN ISSUES

L<autodie> creates functions named, e.g., C<chmod> in the
namespace of the module that C<import()>s it. Those functions lack
the compiler “hint” that tells Sys::Binmode to do its work; thus,
L<autodie “clobbers” Sys::Binmode|https://github.com/pjf/autodie/issues/113>.
C<CORE::*> functions will still have Sys::Binmode, but of course they won’t
throw exceptions.

=head1 TODO

=over

=item * C<dbmopen> and the System V IPC functions aren’t covered here.
If you’d like them, ask.

=item * There’s room for optimization, if that’s gainful.

=item * Ideally this behavior should be in Perl’s core distribution.

=item * Even more ideally, Perl should adopt this behavior as I<default>.
Maybe someday!

=back

=cut

#----------------------------------------------------------------------

require XSLoader;
XSLoader::load(__PACKAGE__, $VERSION);

sub import {
    $^H{ _HINT_KEY() } = 1;

    return;
}



( run in 0.938 second using v1.01-cache-2.11-cpan-5511b514fd6 )