diff options
-rw-r--r-- | Doc/lib/libmmap.tex | 6 | ||||
-rw-r--r-- | Lib/test/output/test_mmap | 2 | ||||
-rw-r--r-- | Lib/test/test_mmap.py | 36 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Modules/mmapmodule.c | 13 |
5 files changed, 53 insertions, 7 deletions
diff --git a/Doc/lib/libmmap.tex b/Doc/lib/libmmap.tex index d0fbf88..0d7baa1 100644 --- a/Doc/lib/libmmap.tex +++ b/Doc/lib/libmmap.tex @@ -62,8 +62,10 @@ the underlying file. prot\optional{, access}}}} \strong{(\UNIX{} version)} Maps \var{length} bytes from the file specified by the file descriptor \var{fileno}, and returns a mmap - object. - + object. If \var{length} is \code{0}, the maximum length of the map + will be the current size of the file when \function{mmap(} is + called. + \var{flags} specifies the nature of the mapping. \constant{MAP_PRIVATE} creates a private copy-on-write mapping, so changes to the contents of the mmap object will be private to this diff --git a/Lib/test/output/test_mmap b/Lib/test/output/test_mmap index 1706ad5..02b24bc 100644 --- a/Lib/test/output/test_mmap +++ b/Lib/test/output/test_mmap @@ -31,4 +31,6 @@ test_mmap Modifying copy-on-write memory map. Ensuring copy-on-write maps cannot be resized. Ensuring invalid access parameter raises exception. + Ensuring that passing 0 as map length sets map size to current file size. + Ensuring that passing 0 as map length sets map size to current file size. Test passed diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index a6796d5..d225173 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -311,7 +311,43 @@ def test_both(): finally: os.unlink(TESTFN) + # test mapping of entire file by passing 0 for map length + if hasattr(os, "stat"): + print " Ensuring that passing 0 as map length sets map size to current file size." + f = open(TESTFN, "w+") + try: + f.write(2**16 * 'm') # Arbitrary character + f.close() + + f = open(TESTFN, "rb+") + mf = mmap.mmap(f.fileno(), 0) + verify(len(mf) == 2**16, "Map size should equal file size.") + vereq(mf.read(2**16), 2**16 * "m") + mf.close() + f.close() + + finally: + os.unlink(TESTFN) + + # test mapping of entire file by passing 0 for map length + if hasattr(os, "stat"): + print " Ensuring that passing 0 as map length sets map size to current file size." + f = open(TESTFN, "w+") + try: + f.write(2**16 * 'm') # Arbitrary character + f.close() + + f = open(TESTFN, "rb+") + mf = mmap.mmap(f.fileno(), 0) + verify(len(mf) == 2**16, "Map size should equal file size.") + vereq(mf.read(2**16), 2**16 * "m") + mf.close() + f.close() + + finally: + os.unlink(TESTFN) + print ' Test passed' test_both() @@ -36,6 +36,9 @@ Core and builtins Extension Modules ----------------- +- Patches #749830, #1144555: allow UNIX mmap size to default to current + file size. + - Added functional.partial(). See PEP309. - Patch #1093585: raise a ValueError for negative history items in readline. diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index e1a2f42..aaa4925 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -896,11 +896,14 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) /* on OpenVMS we must ensure that all bytes are written to the file */ fsync(fd); # endif - if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode) && - (size_t)map_size > st.st_size) { - PyErr_SetString(PyExc_ValueError, - "mmap length is greater than file size"); - return NULL; + if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) { + if (map_size == 0) { + map_size = (int)st.st_size; + } else if ((size_t)map_size > st.st_size) { + PyErr_SetString(PyExc_ValueError, + "mmap length is greater than file size"); + return NULL; + } } #endif m_obj = PyObject_New (mmap_object, &mmap_object_type); |