[pypy-svn] pypy default: Fix mmap.resize() when the mmap has an offset.

alex_gaynor commits-noreply at bitbucket.org
Thu Feb 10 20:52:34 CET 2011


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: 
Changeset: r41801:62b77a7d8f53
Date: 2011-02-10 14:51 -0500
http://bitbucket.org/pypy/pypy/changeset/62b77a7d8f53/

Log:	Fix mmap.resize() when the mmap has an offset.

diff --git a/pypy/module/mmap/test/test_mmap.py b/pypy/module/mmap/test/test_mmap.py
--- a/pypy/module/mmap/test/test_mmap.py
+++ b/pypy/module/mmap/test/test_mmap.py
@@ -529,6 +529,35 @@
         m.close()
         f.close()
 
+    def test_offset_more(self):
+        from mmap import mmap, ALLOCATIONGRANULARITY
+
+        with open(self.tmpname, "w+b") as f:
+            halfsize = ALLOCATIONGRANULARITY
+            f.write("\0" * halfsize)
+            f.write("foo")
+            f.write("\0" * (halfsize - 3))
+            m = mmap(f.fileno(), 0)
+            m.close()
+
+        with open(self.tmpname, "r+b") as f:
+            m = mmap(f.fileno(), halfsize, offset=halfsize)
+            assert m[0:3] == "foo"
+
+        try:
+            m.resize(512)
+        except SystemError:
+            pass
+        else:
+            assert len(m) == 512
+            raises(ValueError, m.seek, 513, 0)
+            assert m[0:3] == "foo"
+            with open(self.tmpname) as f:
+                f.seek(0, 2)
+                assert f.tell() == halfsize + 512
+            assert m.size() == halfsize + 512
+        m.close()
+
     def test_all(self):
         # this is a global test, ported from test_mmap.py
         import mmap
@@ -710,4 +739,3 @@
         assert m.read(10) == "ABCDEABCDE"
         m.close()
         f.close()
-

diff --git a/pypy/rlib/rmmap.py b/pypy/rlib/rmmap.py
--- a/pypy/rlib/rmmap.py
+++ b/pypy/rlib/rmmap.py
@@ -261,10 +261,11 @@
 NODATA = lltype.nullptr(PTR.TO)
 
 class MMap(object):
-    def __init__(self, access):
+    def __init__(self, access, offset):
         self.size = 0
         self.pos = 0
         self.access = access
+        self.offset = offset
 
         if _MS_WINDOWS:
             self.map_handle = NULL_HANDLE
@@ -534,7 +535,7 @@
                 raise OSError(-11111, "No mremap available")
             
             # resize the underlying file first
-            os.ftruncate(self.fd, newsize)
+            os.ftruncate(self.fd, self.offset + newsize)
                 
             # now resize the mmap
             newdata = c_mremap(self.getptr(0), self.size, newsize,
@@ -547,11 +548,15 @@
 
             # move to the desired EOF position
             if _64BIT:
-                newsize_high = newsize >> 32
-                newsize_low = newsize & 0xFFFFFFFF
+                newsize_high = (self.offset + newsize) >> 32
+                newsize_low = (self.offset + newsize) & 0xFFFFFFFF
+                offset_high = self.offset >> 32
+                offset_low = self.offset & 0xFFFFFFFF
             else:
                 newsize_high = 0
-                newsize_low = newsize
+                newsize_low = self.offset + newsize
+                offset_high = 0
+                offset_low = self.offset
 
             FILE_BEGIN = 0
             high_ref = lltype.malloc(PLONG.TO, 1, flavor='raw')
@@ -666,7 +671,7 @@
                 elif map_size > size:
                     raise RValueError("mmap length is greater than file size")
 
-        m = MMap(access)
+        m = MMap(access, offset)
         if fd == -1:
             # Assume the caller wants to map anonymous memory.
             # This is the same behaviour as Windows.  mmap.mmap(-1, size)
@@ -753,7 +758,7 @@
             # SEEK_SET = 0
             # libc._lseek(fileno, 0, SEEK_SET)
         
-        m = MMap(access)
+        m = MMap(access, offset)
         m.file_handle = INVALID_HANDLE
         m.map_handle = INVALID_HANDLE
         if fh:


More information about the Pypy-commit mailing list