@@ -119,12 +119,12 @@ typedef struct {
119119
120120#ifdef UNIX
121121 int fd ;
122- _Bool trackfd ;
123122 int flags ;
124123#endif
125124
126125 PyObject * weakreflist ;
127126 access_mode access ;
127+ _Bool trackfd ;
128128} mmap_object ;
129129
130130#define mmap_object_CAST (op ) ((mmap_object *)(op))
@@ -636,13 +636,11 @@ is_resizeable(mmap_object *self)
636636 "mmap can't resize with extant buffers exported." );
637637 return 0 ;
638638 }
639- #ifdef UNIX
640639 if (!self -> trackfd ) {
641640 PyErr_SetString (PyExc_ValueError ,
642641 "mmap can't resize with trackfd=False." );
643642 return 0 ;
644643 }
645- #endif
646644 if ((self -> access == ACCESS_WRITE ) || (self -> access == ACCESS_DEFAULT ))
647645 return 1 ;
648646 PyErr_Format (PyExc_TypeError ,
@@ -734,8 +732,6 @@ mmap_size_method(PyObject *op, PyObject *Py_UNUSED(ignored))
734732 return PyLong_FromLong ((long )low );
735733 size = (((long long )high )<<32 ) + low ;
736734 return PyLong_FromLongLong (size );
737- } else {
738- return PyLong_FromSsize_t (self -> size );
739735 }
740736#endif /* MS_WINDOWS */
741737
@@ -750,6 +746,7 @@ mmap_size_method(PyObject *op, PyObject *Py_UNUSED(ignored))
750746 return PyLong_FromLong (status .st_size );
751747#endif
752748 }
749+ #endif /* UNIX */
753750 else if (self -> trackfd ) {
754751 return PyLong_FromSsize_t (self -> size );
755752 }
@@ -758,7 +755,6 @@ mmap_size_method(PyObject *op, PyObject *Py_UNUSED(ignored))
758755 "can't get size with trackfd=False" );
759756 return NULL ;
760757 }
761- #endif /* UNIX */
762758}
763759
764760/* This assumes that you want the entire file mapped,
@@ -1476,7 +1472,7 @@ static PyObject *
14761472new_mmap_object (PyTypeObject * type , PyObject * args , PyObject * kwdict );
14771473
14781474PyDoc_STRVAR (mmap_doc ,
1479- "Windows: mmap(fileno, length[, tagname[, access[, offset]]])\n\
1475+ "Windows: mmap(fileno, length[, tagname[, access[, offset[, trackfd] ]]])\n\
14801476\n\
14811477Maps length bytes from the file specified by the file handle fileno,\n\
14821478and returns a mmap object. If length is larger than the current size\n\
@@ -1737,16 +1733,17 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
17371733 PyObject * tagname = Py_None ;
17381734 DWORD dwErr = 0 ;
17391735 int fileno ;
1740- HANDLE fh = 0 ;
1736+ HANDLE fh = INVALID_HANDLE_VALUE ;
17411737 int access = (access_mode )ACCESS_DEFAULT ;
1738+ int trackfd = 1 ;
17421739 DWORD flProtect , dwDesiredAccess ;
17431740 static char * keywords [] = { "fileno" , "length" ,
17441741 "tagname" ,
1745- "access" , "offset" , NULL };
1742+ "access" , "offset" , "trackfd" , NULL };
17461743
1747- if (!PyArg_ParseTupleAndKeywords (args , kwdict , "in|OiL" , keywords ,
1744+ if (!PyArg_ParseTupleAndKeywords (args , kwdict , "in|OiL$p " , keywords ,
17481745 & fileno , & map_size ,
1749- & tagname , & access , & offset )) {
1746+ & tagname , & access , & offset , & trackfd )) {
17501747 return NULL ;
17511748 }
17521749
@@ -1813,30 +1810,36 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
18131810 m_obj -> map_handle = NULL ;
18141811 m_obj -> tagname = NULL ;
18151812 m_obj -> offset = offset ;
1813+ m_obj -> trackfd = trackfd ;
18161814
1817- if (fh ) {
1818- /* It is necessary to duplicate the handle, so the
1819- Python code can close it on us */
1820- if (!DuplicateHandle (
1821- GetCurrentProcess (), /* source process handle */
1822- fh , /* handle to be duplicated */
1823- GetCurrentProcess (), /* target proc handle */
1824- (LPHANDLE )& m_obj -> file_handle , /* result */
1825- 0 , /* access - ignored due to options value */
1826- FALSE, /* inherited by child processes? */
1827- DUPLICATE_SAME_ACCESS )) { /* options */
1828- dwErr = GetLastError ();
1829- Py_DECREF (m_obj );
1830- PyErr_SetFromWindowsErr (dwErr );
1831- return NULL ;
1815+ if (fh != INVALID_HANDLE_VALUE ) {
1816+ if (trackfd ) {
1817+ /* It is necessary to duplicate the handle, so the
1818+ Python code can close it on us */
1819+ if (!DuplicateHandle (
1820+ GetCurrentProcess (), /* source process handle */
1821+ fh , /* handle to be duplicated */
1822+ GetCurrentProcess (), /* target proc handle */
1823+ & fh , /* result */
1824+ 0 , /* access - ignored due to options value */
1825+ FALSE, /* inherited by child processes? */
1826+ DUPLICATE_SAME_ACCESS )) /* options */
1827+ {
1828+ dwErr = GetLastError ();
1829+ Py_DECREF (m_obj );
1830+ PyErr_SetFromWindowsErr (dwErr );
1831+ return NULL ;
1832+ }
1833+ m_obj -> file_handle = fh ;
18321834 }
18331835 if (!map_size ) {
18341836 DWORD low ,high ;
18351837 low = GetFileSize (fh , & high );
18361838 /* low might just happen to have the value INVALID_FILE_SIZE;
18371839 so we need to check the last error also. */
18381840 if (low == INVALID_FILE_SIZE &&
1839- (dwErr = GetLastError ()) != NO_ERROR ) {
1841+ (dwErr = GetLastError ()) != NO_ERROR )
1842+ {
18401843 Py_DECREF (m_obj );
18411844 return PyErr_SetFromWindowsErr (dwErr );
18421845 }
@@ -1898,7 +1901,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
18981901 off_lo = (DWORD )(offset & 0xFFFFFFFF );
18991902 /* For files, it would be sufficient to pass 0 as size.
19001903 For anonymous maps, we have to pass the size explicitly. */
1901- m_obj -> map_handle = CreateFileMappingW (m_obj -> file_handle ,
1904+ m_obj -> map_handle = CreateFileMappingW (fh ,
19021905 NULL ,
19031906 flProtect ,
19041907 size_hi ,
0 commit comments