From da322e1492202c11205990962dee9c4e093dfb1f Mon Sep 17 00:00:00 2001 From: Bruce Armstrong Date: Wed, 10 Feb 2016 00:39:23 -0700 Subject: [PATCH 1/2] Fix for issue #1, Crash with non-0 offset Use sv_chop to set up offset hack to alert perl --- Mmap.xs | 11 ++++++----- t/on_exit.t | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 t/on_exit.t diff --git a/Mmap.xs b/Mmap.xs index df6b28d..d1b4c9e 100644 --- a/Mmap.xs +++ b/Mmap.xs @@ -224,12 +224,13 @@ mmap(var, len, prot, flags, fh = 0, off_string) if (!(prot & PROT_WRITE)) SvREADONLY_on(var); - /* would sv_usepvn() be cleaner/better/different? would still try to realloc... */ - SvPVX(var) = (char *) addr + slop; - SvCUR_set(var, len); - SvLEN_set(var, slop); + SvPVX(var) = (char *) addr; + SvCUR_set(var, len + slop); + if (slop > 0) { + sv_chop(var, addr + slop); + } SvPOK_only(var); - ST(0) = sv_2mortal(newSVnv((IV) addr)); + ST(0) = sv_2mortal(newSViv((IV) addr)); SV * munmap(var) diff --git a/t/on_exit.t b/t/on_exit.t new file mode 100644 index 0000000..ac6a1e7 --- /dev/null +++ b/t/on_exit.t @@ -0,0 +1,26 @@ +#! perl + +BEGIN { + use strict; + use warnings; + use Test::More tests => 1; + + use_ok('Sys::Mmap'); +} + +use FileHandle; + +my $temp_file = "mmap.tmp"; + +my $temp_file_contents = "0" x 1000; +sysopen(FOO, $temp_file, O_WRONLY|O_CREAT|O_TRUNC) or die "$temp_file: $!\n"; +print FOO $temp_file_contents; +close FOO; + +# Perl was segfaulting when exiting after using a non zero offset +# The key here is that munmap was not done before exiting +my $foo; +sysopen(FOO, $temp_file, O_RDWR) or die "$temp_file: $!\n"; +mmap($foo, 0, PROT_READ, MAP_SHARED, FOO, 256); + +unlink($temp_file); From 78a7ce2d72e853afdf86d36956b63dab36e88f3e Mon Sep 17 00:00:00 2001 From: Bruce Armstrong Date: Thu, 11 Feb 2016 23:02:36 -0700 Subject: [PATCH 2/2] Added test for offset --- t/mmap.t | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/t/mmap.t b/t/mmap.t index ba0afa7..a1dc9e3 100644 --- a/t/mmap.t +++ b/t/mmap.t @@ -3,7 +3,7 @@ BEGIN { use strict; use warnings; - use Test::More tests => 8; + use Test::More tests => 9; use_ok('Sys::Mmap'); } @@ -38,6 +38,12 @@ substr($temp_file_contents, 3, 1) = "Z"; is($foo, $temp_file_contents, 'Foo can be altered in RW mode'); munmap($foo); +sysopen(FOO, $temp_file, O_RDWR) or die "$temp_file: $!\n"; +mmap($foo, 0, PROT_READ|PROT_WRITE, MAP_SHARED, FOO, 5); +close FOO; +is(substr($foo, 5, 1), '2', 'Offset handled'); +munmap($foo); + sysopen(FOO, $temp_file, O_RDONLY) or die "$temp_file: $!\n"; my $bar = ; is($bar, $temp_file_contents, 'Altered foo reflects on disk');