diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst --- a/Doc/library/mmap.rst +++ b/Doc/library/mmap.rst @@ -86,6 +86,10 @@ defaults to 0. *offset* must be a multiple of the PAGESIZE or ALLOCATIONGRANULARITY. + To ensure validity of the created memory mapping the file specified + by the descriptor *fileno* is internally automatically synchronized + with physical backing store on Mac OS X and OpenVMS. + This example shows a simple way of using :class:`mmap`:: import mmap diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py --- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -70,7 +70,7 @@ with open(support.TESTFN, "wb+") as f: f.seek(_4G) f.write(b"asdf") - with open(support.TESTFN, "rb") as f: + f.flush() self.mapping = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) def tearDown(self): diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -23,6 +23,9 @@ #ifndef MS_WINDOWS #define UNIX +# ifdef __APPLE__ +# include +# endif #endif #ifdef MS_WINDOWS @@ -1122,6 +1125,13 @@ "mmap invalid access parameter."); } +#ifdef __APPLE__ + /* Issue 11277: due to lack of sparse file support on OS X synchronization + * with physical backing store is required to ensure validity of the mmap. + * Since fsync(2) acts like fdatasync(2) a special fcntl(2) is necessary */ + if (fd != -1) + (void)fcntl(fd, F_FULLFSYNC); +#endif #ifdef HAVE_FSTAT # ifdef __VMS /* on OpenVMS we must ensure that all bytes are written to the file */