Selkie.git | lib/Selkie/App/Internal/ | ErrorLogPlatform.rakumod
=begin pod
=head1 NAME
Selkie::App::Internal::ErrorLogPlatform - platform fd adapter for error logging
=head1 DESCRIPTION
Internal implementation detail used by C<Selkie::App::Internal::ErrorLog>.
=end pod
unit module Selkie::App::Internal::ErrorLogPlatform;
use NativeCall;
use Selkie::App::Internal::PosixFD;
# Official Windows MoarVM builds use /MT, so their integer file descriptors
# belong to a private, statically linked CRT. No NativeCall DLL owns that
# descriptor table. Windows therefore redirects Raku's PROCESS::<$ERR>
# object and the independent Win32 standard handle; only POSIX mutates fd 2.
our sub error-log-api-spec(Bool:D $is-win --> Map:D) is export(:test) {
$is-win
?? Map.new(
api => "win32",
library => "kernel32",
create-file => "CreateFileW",
close-handle => "CloseHandle",
)
!! Map.new(
api => "posix",
library => Str,
dup => "dup",
dup2 => "dup2",
close => "close",
)
}
our constant IS-WINDOWS is export = $*DISTRO.is-win;
our constant WINDOWS-STD-ERROR-HANDLE is export = 0xFFFF_FFF4;
our constant WINDOWS-FILE-APPEND-DATA is export = 0x0000_0004;
our constant WINDOWS-SYNCHRONIZE is export = 0x0010_0000;
our constant WINDOWS-FILE-SHARE-ALL is export = 0x0000_0007;
our constant WINDOWS-OPEN-ALWAYS is export = 4;
our constant WINDOWS-FILE-ATTRIBUTE-NORMAL is export = 0x0000_0080;
our sub fd-dup(int32 $fd --> int32) is export {
posix-fd-dup($fd)
}
our sub fd-dup2(int32 $source, int32 $target --> int32) is export {
posix-fd-dup2($source, $target)
}
our sub fd-close(int32 $fd --> int32) is export {
posix-fd-close($fd)
}
# GetStdHandle and SetStdHandle take a DWORD, not a signed integer. The
# standard-handle constants are C casts such as ((DWORD)-12), whose value at
# the ABI boundary is the unsigned 32-bit integer 0xFFFFFFF4. Passing -12 as
# an int32 is not portable through foreign-function interfaces.
our sub windows-get-std-handle(uint32 --> Pointer) is export
is native("kernel32") is symbol("GetStdHandle") { * }
our sub windows-set-std-handle(uint32, Pointer --> int32) is export
is native("kernel32") is symbol("SetStdHandle") { * }
our sub windows-create-file(
Str is encoded("utf16"), uint32, uint32, Pointer,
uint32, uint32, Pointer --> Pointer
) is export is native("kernel32") is symbol("CreateFileW") { * }
our sub windows-close-handle(Pointer --> int32) is export
is native("kernel32") is symbol("CloseHandle") { * }