[pypy-svn] pypy default: Give the offset keyword argument to mmap().
arigo
commits-noreply at bitbucket.org
Thu Feb 10 17:03:10 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r41788:943e58cee14c
Date: 2011-02-10 17:02 +0100
http://bitbucket.org/pypy/pypy/changeset/943e58cee14c/
Log: Give the offset keyword argument to mmap().
diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py
--- a/pypy/module/mmap/interp_mmap.py
+++ b/pypy/module/mmap/interp_mmap.py
@@ -5,7 +5,7 @@
from pypy.interpreter.typedef import TypeDef
from pypy.interpreter.gateway import interp2app, NoneNotWrapped
from pypy.rlib import rmmap
-from pypy.rlib.rmmap import RValueError, RTypeError
+from pypy.rlib.rmmap import RValueError, RTypeError, ROverflowError
import sys
import os
import platform
@@ -207,36 +207,42 @@
def mmap(space, w_subtype, fileno, length, flags=rmmap.MAP_SHARED,
prot=rmmap.PROT_WRITE | rmmap.PROT_READ,
- access=rmmap._ACCESS_DEFAULT):
+ access=rmmap._ACCESS_DEFAULT, offset=0):
self = space.allocate_instance(W_MMap, w_subtype)
try:
W_MMap.__init__(self, space,
- rmmap.mmap(fileno, length, flags, prot, access))
+ rmmap.mmap(fileno, length, flags, prot, access,
+ offset))
except OSError, e:
raise mmap_error(space, e)
except RValueError, e:
raise OperationError(space.w_ValueError, space.wrap(e.message))
except RTypeError, e:
raise OperationError(space.w_TypeError, space.wrap(e.message))
+ except ROverflowError, e:
+ raise OperationError(space.w_OverflowError, space.wrap(e.message))
return space.wrap(self)
- mmap.unwrap_spec = [ObjSpace, W_Root, int, 'index', int, int, int]
+ mmap.unwrap_spec = [ObjSpace, W_Root, int, 'index', int, int, int, 'index']
elif rmmap._MS_WINDOWS:
def mmap(space, w_subtype, fileno, length, tagname="",
- access=rmmap._ACCESS_DEFAULT):
+ access=rmmap._ACCESS_DEFAULT, offset=0):
self = space.allocate_instance(W_MMap, w_subtype)
try:
W_MMap.__init__(self, space,
- rmmap.mmap(fileno, length, tagname, access))
+ rmmap.mmap(fileno, length, tagname, access,
+ offset))
except OSError, e:
raise mmap_error(space, e)
except RValueError, e:
raise OperationError(space.w_ValueError, space.wrap(e.message))
except RTypeError, e:
raise OperationError(space.w_TypeError, space.wrap(e.message))
+ except ROverflowError, e:
+ raise OperationError(space.w_OverflowError, space.wrap(e.message))
return space.wrap(self)
- mmap.unwrap_spec = [ObjSpace, W_Root, int, 'index', str, int]
+ mmap.unwrap_spec = [ObjSpace, W_Root, int, 'index', str, int, 'index']
W_MMap.typedef = TypeDef("mmap",
__new__ = interp2app(mmap),
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
@@ -518,6 +518,17 @@
assert b[3] == "b"
assert b[:] == "foobar"
+ def test_offset(self):
+ from mmap import mmap
+ f = open(self.tmpname + "y", "w+")
+ f.write("foobar" * 3000)
+ f.flush()
+ m = mmap(f.fileno(), 4, offset=8192)
+ assert m[:] == "obar"
+ assert len(m) == 4
+ m.close()
+ f.close()
+
def test_all(self):
# this is a global test, ported from test_mmap.py
import mmap
diff --git a/pypy/rlib/rmmap.py b/pypy/rlib/rmmap.py
--- a/pypy/rlib/rmmap.py
+++ b/pypy/rlib/rmmap.py
@@ -21,7 +21,11 @@
class RTypeError(Exception):
def __init__(self, message):
- self.message = message
+ self.message = message
+
+class ROverflowError(Exception):
+ def __init__(self, message):
+ self.message = message
includes = ["sys/types.h"]
if _POSIX:
@@ -607,11 +611,11 @@
if size < 0:
raise RTypeError("memory mapped size must be positive")
if rffi.cast(size_t, size) != size:
- raise OverflowError("memory mapped size is too large (limited by C int)")
+ raise ROverflowError("memory mapped size is too large (limited by C int)")
if _POSIX:
def mmap(fileno, length, flags=MAP_SHARED,
- prot=PROT_WRITE | PROT_READ, access=_ACCESS_DEFAULT):
+ prot=PROT_WRITE | PROT_READ, access=_ACCESS_DEFAULT, offset=0):
fd = fileno
@@ -623,6 +627,8 @@
# check size boundaries
_check_map_size(length)
map_size = length
+ if offset < 0:
+ raise RValueError("negative offset")
if access == ACCESS_READ:
flags = MAP_SHARED
@@ -649,6 +655,7 @@
else:
mode = st[stat.ST_MODE]
size = st[stat.ST_SIZE]
+ size -= offset
if size > sys.maxint:
size = sys.maxint
else:
@@ -674,7 +681,7 @@
# XXX if we use hintp below in alloc, the NonConstant
# is necessary since we want a general version of c_mmap
# to be annotated with a non-constant pointer.
- res = c_mmap(NonConstant(NULL), map_size, prot, flags, fd, 0)
+ res = c_mmap(NonConstant(NULL), map_size, prot, flags, fd, offset)
if res == rffi.cast(PTR, -1):
errno = _get_error_no()
raise OSError(errno, os.strerror(errno))
@@ -711,10 +718,12 @@
free = c_munmap_safe
elif _MS_WINDOWS:
- def mmap(fileno, length, tagname="", access=_ACCESS_DEFAULT):
+ def mmap(fileno, length, tagname="", access=_ACCESS_DEFAULT, offset=0):
# check size boundaries
_check_map_size(length)
map_size = length
+ if offset < 0:
+ raise RValueError("negative offset")
flProtect = 0
dwDesiredAccess = 0
@@ -785,16 +794,20 @@
if _64BIT:
size_hi = map_size >> 32
size_lo = map_size & 0xFFFFFFFF
+ offset_hi = offset >> 32
+ offset_lo = offset & 0xFFFFFFFF
else:
size_hi = 0
size_lo = map_size
+ offset_hi = 0
+ offset_lo = offset
m.map_handle = CreateFileMapping(m.file_handle, NULL, flProtect,
size_hi, size_lo, m.tagname)
if m.map_handle:
res = MapViewOfFile(m.map_handle, dwDesiredAccess,
- 0, 0, 0)
+ offset_hi, offset_lo, 0)
if res:
# XXX we should have a real LPVOID which must always be casted
charp = rffi.cast(LPCSTR, res)
More information about the Pypy-commit
mailing list