summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/lib/libmmap.tex6
-rw-r--r--Lib/test/output/test_mmap2
-rw-r--r--Lib/test/test_mmap.py36
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/mmapmodule.c13
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()
diff --git a/Misc/NEWS b/Misc/NEWS
index ea463f9..708404d 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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);