Permalink
Browse files

Fixes to handle large file systems

* Mmap could not handle files larger than 2GB if perl was not using 64bit int.
  Resolved the problem by taking a string and converting it via atoll,
  depending on _FILE_OFFSET_BITS > 32
* Added test and fix to croak if a negative offset is passed in.
* initialize global variable pagesize = 0 so it'll set right the first time
* Remove typemap which was only used by mmap sub. Now we're using SV,
  it's no longer an issue.
  • Loading branch information...
1 parent 33fb4c5 commit 61771697729001eb40029ea06a79625faaf99738 @cpanel cpanel committed Mar 29, 2011
Showing with 47 additions and 15 deletions.
  1. +7 −7 .gitignore
  2. +9 −0 Changes
  3. +0 −1 MANIFEST
  4. +1 −1 Mmap.pm
  5. +25 −4 Mmap.xs
  6. +5 −1 t/mmap.t
  7. +0 −1 typemap
View
@@ -1,7 +1,7 @@
-Makefile
-Makefile.old
-Mmap.bs
-Mmap.c
-Mmap.o
-blib/
-pm_to_blib
+/Makefile
+/Makefile.old
+/Mmap.bs
+/Mmap.c
+/Mmap.o
+/blib/
+/pm_to_blib
View
@@ -1,3 +1,12 @@
+Todd Rinaldo March 29 2011 v0.14_01
+* Mmap could not handle files larger than 2GB if perl was not using 64bit int.
+ Resolved the problem by taking a string and converting it via atoll,
+ depending on _FILE_OFFSET_BITS > 32
+* Added test and fix to croak if a negative offset is passed in.
+* initialize global variable pagesize = 0 so it'll set right the first time
+* Remove typemap which was only used by mmap sub. Now we're using SV,
+ it's no longer an issue.
+
Todd Rinaldo Sept 7 2010 v0.14
* Tests look stable. Releasing prod version of module.
View
@@ -9,4 +9,3 @@ Mmap.xs
README
t/mmap.t
t/munmap_errors.t
-typemap
View
@@ -188,7 +188,7 @@ require Exporter;
MAP_ANON MAP_ANONYMOUS MAP_FILE MAP_PRIVATE MAP_SHARED
PROT_EXEC PROT_NONE PROT_READ PROT_WRITE);
-$VERSION = '0.14';
+$VERSION = '0.14_01';
sub new {
View
@@ -4,6 +4,7 @@ extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
+#include <stdlib.h>
#ifdef __cplusplus
}
#endif
@@ -113,7 +114,14 @@ not_there:
return 0;
}
-static size_t pagesize;
+static size_t pagesize = 0;
+
+
+#if _FILE_OFFSET_BITS > 32
+#define get_off(a) (atoll(a))
+#else
+#define get_off(a) (atoi(a))
+#endif
MODULE = Sys::Mmap PACKAGE = Sys::Mmap
@@ -141,20 +149,33 @@ hardwire(var, addr, len)
ST(0) = &PL_sv_yes;
+
SV *
-mmap(var, len, prot, flags, fh = 0, off = 0)
+mmap(var, len, prot, flags, fh = 0, off_string)
SV * var
size_t len
int prot
int flags
FILE * fh
- off_t off
+ SV * off_string
int fd = NO_INIT
MMAP_RETTYPE addr = NO_INIT
off_t slop = NO_INIT
+ off_t off = NO_INIT
PROTOTYPE: $$$$*;$
CODE:
+ if(!SvTRUE(off_string)) {
+ off = 0;
+ }
+ else {
+ off = get_off(SvPVbyte_nolen(off_string));
+ }
+
+ if(off < 0) {
+ croak("mmap: Cannot operate on a negative offset (%s) ", SvPVbyte_nolen(off_string));
+ }
+
ST(0) = &PL_sv_undef;
if(flags&MAP_ANON) {
fd = -1;
@@ -180,7 +201,7 @@ mmap(var, len, prot, flags, fh = 0, off = 0)
pagesize = getpagesize();
}
- slop = off % pagesize;
+ slop = (size_t) off % pagesize;
addr = mmap(0, len + slop, prot, flags, fd, off - slop);
if (addr == MAP_FAILED) {
View
@@ -3,7 +3,7 @@
BEGIN {
use strict;
use warnings;
- use Test::More tests => 4;
+ use Test::More tests => 6;
use_ok('Sys::Mmap');
}
@@ -18,6 +18,10 @@ close FOO;
my $foo;
sysopen(FOO, $temp_file, O_RDONLY) or die "$temp_file: $!\n";
+# Test negative offsets fail.
+is(eval { mmap($foo, 0, PROT_READ, MAP_SHARED, FOO, -100); 1}, undef, "Negative seek fails.");
+like($@, qr/^\Qmmap: Cannot operate on a negative offset (-100)\E/, "croaks when negative offset is passed in");
+# Now map the file for real
mmap($foo, 0, PROT_READ, MAP_SHARED, FOO);
close FOO;
View
@@ -1 +0,0 @@
-off_t T_IV

0 comments on commit 6177169

Please sign in to comment.