use Config;
use strict;
our $VERSION = "1.09_00";
my %err = ();
my %wsa = ();
select OUT;
my $file;
process_file($file);
}
unlink "errno.c" if -f "errno.c";
sub process_file {
my($file) = @_;
# warn "Processing $file\n";
local *FH;
warn "Cannot open '$file'";
return;
}
# OpenSTEP has gcc 2.7.2.1 which recognizes but
# doesn't implement the -dM flag.
&& $^O ne 'openstep' && $^O ne 'next' && $^O ne 'darwin'
) {
# With the -dM option, gcc outputs every #define it finds
unless(open(FH,"$Config{cc} -E -dM $Config{cppflags} $file |")) {
warn "Cannot open '$file'";
return;
}
} else {
unless(open(FH,"< $file")) {
# This file could be a temporary file created by cppstdin
# so only warn under -w, and return
warn "Cannot open '$file'" if $^W;
return;
}
}
if ($^O eq 'MacOS') {
while(<FH>) {
if /^\s*#\s*define\s+(E\w+)\s+(\d+)/;
}
} else {
while(<FH>) {
if /^\s*#\s*define\s+(E\w+)\s+/;
if ($^O eq 'MSWin32') {
if /^\s*#\s*define\s+WSA(E\w+)\s+/;
}
}
}
close(FH);
}
my $cppstdin;
sub default_cpp {
unless (defined $cppstdin) {
"cppstdin");
my $cppstdin_is_wrapper =
($cppstdin eq 'cppstdin'
and -f $upup_cppstdin
and -x $upup_cppstdin);
}
return "$cppstdin $Config{cppflags} $Config{cppminus}";
}
sub get_files {
my %file = ();
# VMS keeps its include files in system libraries (well, except for Gcc)
if ($^O eq 'VMS') {
}
} elsif ($^O eq 'os390') {
# OS/390 C compiler doesn't generate #file or #line directives
} elsif ($^O eq 'vmesa') {
# OS/390 C compiler doesn't generate #file or #line directives
# Watch out for cross compiling for EPOC (usually done on linux)
} elsif ($^O eq 'linux' &&
) {
# Some Linuxes have weird errno.hs which generate
# no #file or #line directives
my $linux_errno_h = -e '/usr/include/errno.h' ?
} elsif ($^O eq 'MacOS') {
# note that we are only getting the GUSI errno's here ...
# we might miss out on compiler-specific ones
} elsif ($^O eq 'beos') {
# hidden in a special place
} elsif ($^O eq 'vos') {
# avoid problem where cpp returns non-POSIX pathnames
} else {
open(CPPI,"> errno.c") or
die "Cannot open errno.c";
if ($^O eq 'NetWare') {
print CPPI "#include <nwerrno.h>\n";
} else {
print CPPI "#include <errno.h>\n";
if ($^O eq 'MSWin32') {
print CPPI "#include <winsock.h>\n";
}
}
close(CPPI);
# invoke CPP and read the output
if ($^O eq 'MSWin32' || $^O eq 'NetWare') {
open(CPPO,"$Config{cpprun} $Config{cppflags} errno.c |") or
die "Cannot run '$Config{cpprun} $Config{cppflags} errno.c'";
} else {
my $cpp = default_cpp();
open(CPPO,"$cpp < errno.c |") or
die "Cannot exec $cpp";
}
my $pat;
$pat = '^/\*\s+(.+)\s+\d+\s*:\s+\*/';
}
else {
$pat = '^#\s*(?:line)?\s*\d+\s+"([^"]+)"';
}
while(<CPPO>) {
if ($^O eq 'os2' or $^O eq 'MSWin32' or $^O eq 'NetWare') {
if (/$pat/o) {
my $f = $1;
$f =~ s,\\\\,/,g;
$file{$f} = 1;
}
}
else {
}
}
close(CPPO);
}
return keys %file;
}
sub write_errno_pm {
my $err;
# quick sanity check
die "No error definitions found" unless keys %err;
# create the CPP input
open(CPPI,"> errno.c") or
die "Cannot open errno.c";
if ($^O eq 'NetWare') {
print CPPI "#include <nwerrno.h>\n";
}
else {
print CPPI "#include <errno.h>\n";
}
if ($^O eq 'MSWin32') {
print CPPI "#include <winsock.h>\n";
print CPPI "#ifndef $err\n";
print CPPI "#define $err WSA$err\n";
print CPPI "#endif\n";
}
}
}
close(CPPI);
unless ($^O eq 'MacOS') { # trust what we have
# invoke CPP and read the output
if ($^O eq 'VMS') {
my $cpp = "$Config{cppstdin} $Config{cppflags} $Config{cppminus}";
open(CPPO,"$cpp errno.c |") or
die "Cannot exec $Config{cppstdin}";
} elsif ($^O eq 'MSWin32' || $^O eq 'NetWare') {
open(CPPO,"$Config{cpprun} $Config{cppflags} errno.c |") or
die "Cannot run '$Config{cpprun} $Config{cppflags} errno.c'";
} else {
my $cpp = default_cpp();
open(CPPO,"$cpp < errno.c |")
or die "Cannot exec $cpp";
}
%err = ();
while(<CPPO>) {
}
else {
}
}
close(CPPO);
}
# Many of the E constants (including ENOENT, which is being
# used in the Perl test suite a lot), are available only as
# enums in BeOS, so compiling and executing some code is about
# only way to find out what the numeric Evalues are.
if ($^O eq 'beos') {
if (open(C, ">errno.c")) {
print C <<EOF;
#include <errno.h>
#include <stdio.h>
int main() {
for (@zero) {
print C qq[printf("$_ %d\n", $_);]
}
print C "}\n";
close C;
system("cc -o errno errno.c");
unlink("errno.c");
if (open(C, "./errno|")) {
while (<C>) {
}
close(C);
} else {
die "failed to execute ./errno: $!\n";
}
unlink("errno");
} else {
die "failed to create errno.c: $!\n";
}
}
# Write Errno.pm
print <<"EDQ";
#
# This file is auto-generated. ***ANY*** changes here will be lost
#
package Errno;
use Exporter ();
use Config;
use strict;
"\$Config{'archname'}-\$Config{'osvers'}" eq
"$Config{'archname'}-$Config{'osvers'}" or
die "Errno architecture ($Config{'archname'}-$Config{'osvers'}) does not match executable architecture (\$Config{'archname'}-\$Config{'osvers'})";
\$VERSION = "$VERSION";
my $len = 0;
$j =~ s/(.{50,70})\s/$1\n\t/g;
print $j,"\n";
print <<'ESQ';
%EXPORT_TAGS = (
POSIX => [qw(
my $k = join(" ", grep { exists $err{$_} }
$k =~ s/(.{50,70})\s/$1\n\t/g;
print "\t",$k,"\n )]\n);\n\n";
}
print <<'ESQ';
sub TIEHASH { bless [] }
sub FETCH {
my $proto = prototype("Errno::$errname");
my $errno = "";
no strict 'refs';
}
return $errno;
}
sub STORE {
require Carp;
Carp::confess("ERRNO hash is read only!");
}
sub NEXTKEY {
my($k,$v);
while(($k,$v) = each %Errno::) {
my $proto = prototype("Errno::$k");
}
$k
}
sub FIRSTKEY {
my $s = scalar keys %Errno::; # initialize iterator
goto &NEXTKEY;
}
sub EXISTS {
}
tie %!, __PACKAGE__;
1;
=head1 NAME
Errno - System errno constants
=head1 SYNOPSIS
use Errno qw(EINTR EIO :POSIX);
=head1 DESCRIPTION
C<Errno> defines and conditionally exports all the error constants
defined in your system C<errno.h> include file. It has a single export
tag, C<:POSIX>, which will export all POSIX defined error numbers.
C<Errno> also makes C<%!> magic such that each element of C<%!> has a
non-zero value only if C<$!> is set to that value. For example:
use Errno;
if ($!{ENOENT}) {
warn "Get a wife!\n";
} else {
warn "This path is barred: $!";
}
}
If a specified constant C<EFOO> does not exist on the system, C<$!{EFOO}>
returns C<"">. You may use C<exists $!{EFOO}> to check whether the
constant is available on the system.
=head1 CAVEATS
Importing a particular constant may not be very portable, because the
import will fail on platforms that do not have that constant. A more
portable way to set C<$!> to a valid value is to use:
if (exists &Errno::EFOO) {
$! = &Errno::EFOO;
}
=head1 AUTHOR
Graham Barr <gbarr@pobox.com>
=head1 COPYRIGHT
Copyright (c) 1997-8 Graham Barr. All rights reserved.
under the same terms as Perl itself.
=cut
}