Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Moved protection flags into XS

  • Loading branch information...
commit 99ad4a83366d78d3f01b428ccf54544b975fc51c 1 parent 5c3f0de
@Leont authored
Showing with 32 additions and 20 deletions.
  1. +1 −0  Changes
  2. +2 −9 lib/File/Map.pm
  3. +29 −11 lib/File/Map.xs
View
1  Changes
@@ -2,6 +2,7 @@ Revision history for File-Map
{{$NEXT}}
Switch to Sub::Exporter::Progressive
+ Moved protection flags into XS
0.52 2012-07-17 18:10:48 Europe/Bucharest
It's called HAS_STRERROR_R and not HAVE_STRERROR_R
View
11 lib/File/Map.pm
@@ -38,13 +38,6 @@ my %export_data = (
Sub::Exporter::Progressive->import(-setup => { exports => \@export_ok, groups => \%export_tags });
}
-const our %PROTECTION_FOR => (
- '<' => PROT_READ,
- '+<' => PROT_READ | PROT_WRITE,
- '>' => PROT_WRITE,
- '+>' => PROT_READ | PROT_WRITE,
-);
-
const my $ANON_FH => -1;
const my %is_binary => map { ($_ => 1) } qw/unix stdio perlio mmap crlf/; # crlf can be binary, this needs a better check
@@ -75,7 +68,7 @@ sub map_handle {
my (undef, $fh, $mode, $offset, $length) = @_;
my $utf8 = _check_layers($fh);
($offset, $length) = _get_offset_length($offset, $length, $fh);
- _mmap_impl($_[0], $length, $PROTECTION_FOR{ $mode || '<' }, MAP_SHARED | MAP_FILE, fileno $fh, $offset, $utf8);
+ _mmap_impl($_[0], $length, _protection_value($mode || '<'), MAP_SHARED | MAP_FILE, fileno $fh, $offset, $utf8);
return;
}
@@ -87,7 +80,7 @@ sub map_file {
open my $fh, $minimode.$encoding, $filename or croak "Couldn't open file $filename: $!";
my $utf8 = _check_layers($fh);
($offset, $length) = _get_offset_length($offset, $length, $fh);
- _mmap_impl($_[0], $length, $PROTECTION_FOR{$minimode}, MAP_SHARED | MAP_FILE, fileno $fh, $offset, $utf8);
+ _mmap_impl($_[0], $length, _protection_value($minimode), MAP_SHARED | MAP_FILE, fileno $fh, $offset, $utf8);
close $fh or croak "Couldn't close $filename after mapping: $!";
return;
}
View
40 lib/File/Map.xs
@@ -440,18 +440,28 @@ static void magic_end(pTHX_ void* pre_info) {
}
#endif
-static int _protection_value(pTHX_ SV* prot) {
- HV* protections = get_hv("File::Map::PROTECTION_FOR", FALSE);
- if (SvPOK(prot) && hv_exists_ent(protections, prot, 0)) {
- HE* prot_entry = hv_fetch_ent(protections, prot, FALSE, 0);
- return SvIV(HeVAL(prot_entry));
+typedef struct { const char* key; size_t length; int value; } map[];
+
+static map prots = {
+ { STR_WITH_LEN("<"), PROT_READ },
+ { STR_WITH_LEN("+<"), PROT_READ | PROT_WRITE },
+ { STR_WITH_LEN(">"), PROT_WRITE },
+ { STR_WITH_LEN("+>"), PROT_READ | PROT_WRITE },
+};
+
+static int S_protection_value(pTHX_ SV* mode, int fallback) {
+ int i;
+ STRLEN len;
+ const char* value = SvPV(mode, len);
+ for (i = 0; i < sizeof prots / sizeof *prots; ++i) {
+ if (prots[i].length == len && strEQ(value, prots[i].key))
+ return prots[i].value;
}
- else if (SvIOK(prot))
- return SvIV(prot);
- Perl_croak(aTHX_ "Unknown protection value '%s'", SvPV_nolen(prot));
+ if (fallback && SvIOK(mode))
+ return SvIV(mode);
+ Perl_croak(aTHX_ "No such mode '%s' known", mode);
}
-
-#define protection_value(prot) _protection_value(aTHX_ prot)
+#define protection_value(prot, fallback) S_protection_value(aTHX_ prot, fallback)
#define YES &PL_sv_yes
@@ -571,6 +581,14 @@ _mmap_impl(var, length, prot, flags, fd, offset, utf8 = 0)
add_magic(aTHX_ var, magical, &empty_table, prot & PROT_WRITE, utf8);
}
+int
+_protection_value(mode)
+ SV* mode;
+ CODE:
+ RETVAL = protection_value(mode, FALSE);
+ OUTPUT:
+ RETVAL
+
void
sync(var, sync = YES)
SV* var;
@@ -669,7 +687,7 @@ protect(var, prot)
SV* prot;
PREINIT:
struct mmap_info* info = get_mmap_magic(aTHX_ var, "protect");
- int prot_val = protection_value(prot);
+ int prot_val = protection_value(prot, TRUE);
CODE:
if (!EMPTY_MAP(info))
mprotect(info->real_address, info->real_length, prot_val);
Please sign in to comment.
Something went wrong with that request. Please try again.