Sys-Binmode
view release on metacpan or search on metacpan
OS happens entirely through byte strings. Thus, treating all
OS-destined strings as byte strings is good and natural.
In Windows, though, things are weirder. For example, Windows
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 _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.
# WHERE ELSE THIS PROBLEM CAN APPEAR
The unpredictable-behavior problem that this module fixes in core Perl is
also common in [CPAN](http://cpan.org)âs XS modules due to rampant
use of [the SvPV macro](https://perldoc.perl.org/perlapi#SvPV) and
variants. SvPV is basically Perlâs [bytes](https://metacpan.org/pod/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 [bytes](https://metacpan.org/pod/bytes) pragma is. XS authors
_generally_ should prefer
[SvPVbyte](https://perldoc.perl.org/perlapi#SvPVbyte)
or [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 `char *` and `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.
# LEXICAL SCOPING
If, for some reason, you _want_ Perlâs unpredictable default behavior,
you can disable this module for a given block via
`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
}
# AFFECTED BUILT-INS
- `exec`, `system`, and `readpipe`
- `do` and `require`
- File tests (e.g., `-e`) and the following:
`chdir`, `chmod`, `chown`, `chroot`, `ioctl`,
`link`, `lstat`, `mkdir`, `open`, `opendir`, `readlink`, `rename`,
`rmdir`, `stat`, `symlink`, `sysopen`, `truncate`,
`unlink`, `utime`
- `bind`, `connect`, `setsockopt`, and `send` (last argument)
- `syscall`
## Omissions
- `crypt` already does as Sys::Binmode would make it do.
- `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.
# KNOWN ISSUES
[autodie](https://metacpan.org/pod/autodie) creates functions named, e.g., `chmod` in the
namespace of the module that `import()`s it. Those functions lack
the compiler âhintâ that tells Sys::Binmode to do its work; thus,
[autodie âclobbersâ Sys::Binmode](https://github.com/pjf/autodie/issues/113).
`CORE::*` functions will still have Sys::Binmode, but of course they wonât
throw exceptions.
# TODO
- `dbmopen` and the System V IPC functions arenât covered here.
If youâd like them, ask.
- Thereâs room for optimization, if thatâs gainful.
- Ideally this behavior should be in Perlâs core distribution.
- Even more ideally, Perl should adopt this behavior as _default_.
Maybe someday!
# ACKNOWLEDGEMENTS
Thanks to Leon Timmermans (LEONT) and Paul Evans (PEVANS) for some
debugging and design help.
# LICENSE & COPYRIGHT
Copyright 2021 Gasper Software Consulting. All rights reserved.
This library is licensed under the same license as Perl.
( run in 0.837 second using v1.01-cache-2.11-cpan-5511b514fd6 )