on both Unix (SVR4 and BSD) and Windows. Restores behaviour of passing -1 for anonymous memory on Unix. Use MAP_ANONYMOUS instead of _ANON since the latter is deprecated according to Linux (gentoo) man pages. Should we continue to allow mmap.mmap(0, length) to work on Windows? 0 is a valid fd. Will backport bugfix portions.
This commit is contained in:
parent
d1cfc8ade1
commit
0e6bc8c260
|
@ -37,7 +37,8 @@ taken from the specified file. Assignment to an
|
|||
exception. Assignment to an \constant{ACCESS_WRITE} memory map
|
||||
affects both memory and the underlying file. Assignment to an
|
||||
\constant{ACCESS_COPY} memory map affects memory but does not update
|
||||
the underlying file.
|
||||
the underlying file. \versionchanged[To map anonymous memory,
|
||||
-1 should be passed as the fileno along with the length]{2.5}
|
||||
|
||||
\begin{funcdesc}{mmap}{fileno, length\optional{, tagname\optional{, access}}}
|
||||
\strong{(Windows version)} Maps \var{length} bytes from the file
|
||||
|
|
|
@ -34,4 +34,5 @@ test_mmap
|
|||
Try opening a bad file descriptor...
|
||||
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.
|
||||
anonymous mmap.mmap(-1, PAGESIZE)...
|
||||
Test passed
|
||||
|
|
|
@ -283,7 +283,7 @@ def test_both():
|
|||
|
||||
print ' Try opening a bad file descriptor...'
|
||||
try:
|
||||
mmap.mmap(-1, 4096)
|
||||
mmap.mmap(-2, 4096)
|
||||
except mmap.error:
|
||||
pass
|
||||
else:
|
||||
|
@ -380,6 +380,16 @@ def test_both():
|
|||
finally:
|
||||
os.unlink(TESTFN)
|
||||
|
||||
print ' Test passed'
|
||||
def test_anon():
|
||||
print " anonymous mmap.mmap(-1, PAGESIZE)..."
|
||||
m = mmap.mmap(-1, PAGESIZE)
|
||||
for x in xrange(PAGESIZE):
|
||||
verify(m[x] == '\0', "anonymously mmap'ed contents should be zero")
|
||||
|
||||
for x in xrange(PAGESIZE):
|
||||
m[x] = ch = chr(x & 255)
|
||||
vereq(m[x], ch)
|
||||
|
||||
test_both()
|
||||
test_anon()
|
||||
print ' Test passed'
|
||||
|
|
|
@ -216,6 +216,10 @@ Core and builtins
|
|||
Extension Modules
|
||||
-----------------
|
||||
|
||||
- Patch #1407135, bug #1424041: harmonize mmap behavior of anonymous memory.
|
||||
mmap.mmap(-1, size) now returns anonymous memory in both Unix and Windows.
|
||||
mmap.mmap(0, size) should not be used on Windows for anonymous memory.
|
||||
|
||||
- Patch #1422385: The nis module now supports access to domains other
|
||||
than the system default domain.
|
||||
|
||||
|
|
|
@ -54,6 +54,11 @@ my_getpagesize(void)
|
|||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* maybe define MAP_ANON in terms of MAP_ANONYMOUS */
|
||||
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
|
||||
# define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
|
||||
static PyObject *mmap_module_error;
|
||||
|
||||
typedef enum
|
||||
|
@ -863,6 +868,7 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict)
|
|||
PyObject *map_size_obj = NULL;
|
||||
int map_size;
|
||||
int fd, flags = MAP_SHARED, prot = PROT_WRITE | PROT_READ;
|
||||
int devzero = -1;
|
||||
int access = (int)ACCESS_DEFAULT;
|
||||
static const char *keywords[] = {"fileno", "length",
|
||||
"flags", "prot",
|
||||
|
@ -921,15 +927,41 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict)
|
|||
m_obj->data = NULL;
|
||||
m_obj->size = (size_t) map_size;
|
||||
m_obj->pos = (size_t) 0;
|
||||
m_obj->fd = dup(fd);
|
||||
if (m_obj->fd == -1) {
|
||||
Py_DECREF(m_obj);
|
||||
PyErr_SetFromErrno(mmap_module_error);
|
||||
return NULL;
|
||||
if (fd == -1) {
|
||||
m_obj->fd = -1;
|
||||
/* Assume the caller wants to map anonymous memory.
|
||||
This is the same behaviour as Windows. mmap.mmap(-1, size)
|
||||
on both Windows and Unix map anonymous memory.
|
||||
*/
|
||||
#ifdef MAP_ANONYMOUS
|
||||
/* BSD way to map anonymous memory */
|
||||
flags |= MAP_ANONYMOUS;
|
||||
#else
|
||||
/* SVR4 method to map anonymous memory is to open /dev/zero */
|
||||
fd = devzero = open("/dev/zero", O_RDWR);
|
||||
if (devzero == -1) {
|
||||
Py_DECREF(m_obj);
|
||||
PyErr_SetFromErrno(mmap_module_error);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
m_obj->fd = dup(fd);
|
||||
if (m_obj->fd == -1) {
|
||||
Py_DECREF(m_obj);
|
||||
PyErr_SetFromErrno(mmap_module_error);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
m_obj->data = mmap(NULL, map_size,
|
||||
prot, flags,
|
||||
fd, 0);
|
||||
|
||||
if (devzero != -1) {
|
||||
close(devzero);
|
||||
}
|
||||
|
||||
if (m_obj->data == (char *)-1) {
|
||||
m_obj->data = NULL;
|
||||
Py_DECREF(m_obj);
|
||||
|
@ -986,8 +1018,15 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict)
|
|||
if (map_size < 0)
|
||||
return NULL;
|
||||
|
||||
/* if an actual filename has been specified */
|
||||
if (fileno != 0) {
|
||||
/* assume -1 and 0 both mean invalid filedescriptor
|
||||
to 'anonymously' map memory.
|
||||
XXX: fileno == 0 is a valid fd, but was accepted prior to 2.5.
|
||||
XXX: Should this code be added?
|
||||
if (fileno == 0)
|
||||
PyErr_Warn(PyExc_DeprecationWarning,
|
||||
"don't use 0 for anonymous memory");
|
||||
*/
|
||||
if (fileno != -1 && fileno != 0) {
|
||||
fh = (HANDLE)_get_osfhandle(fileno);
|
||||
if (fh==(HANDLE)-1) {
|
||||
PyErr_SetFromErrno(mmap_module_error);
|
||||
|
@ -1123,10 +1162,10 @@ PyMODINIT_FUNC
|
|||
PyDict_SetItemString (dict, "MAP_EXECUTABLE",
|
||||
PyInt_FromLong(MAP_EXECUTABLE) );
|
||||
#endif
|
||||
#ifdef MAP_ANON
|
||||
PyDict_SetItemString (dict, "MAP_ANON", PyInt_FromLong(MAP_ANON) );
|
||||
#ifdef MAP_ANONYMOUS
|
||||
PyDict_SetItemString (dict, "MAP_ANON", PyInt_FromLong(MAP_ANONYMOUS) );
|
||||
PyDict_SetItemString (dict, "MAP_ANONYMOUS",
|
||||
PyInt_FromLong(MAP_ANON) );
|
||||
PyInt_FromLong(MAP_ANONYMOUS) );
|
||||
#endif
|
||||
|
||||
PyDict_SetItemString (dict, "PAGESIZE",
|
||||
|
|
Loading…
Reference in New Issue