@@ -61,9 +61,14 @@ static void
6161mmap_object_dealloc (mmap_object * m_obj )
6262{
6363#ifdef MS_WIN32
64- UnmapViewOfFile (m_obj -> data );
65- CloseHandle (m_obj -> map_handle );
66- CloseHandle ((HANDLE )m_obj -> file_handle );
64+ if (m_obj -> data != NULL )
65+ UnmapViewOfFile (m_obj -> data );
66+ if (m_obj -> map_handle != INVALID_HANDLE_VALUE )
67+ CloseHandle (m_obj -> map_handle );
68+ if ((HANDLE )m_obj -> file_handle != INVALID_HANDLE_VALUE )
69+ CloseHandle ((HANDLE )m_obj -> file_handle );
70+ if (m_obj -> tagname )
71+ PyMem_Free (m_obj -> tagname );
6772#endif /* MS_WIN32 */
6873
6974#ifdef UNIX
@@ -826,23 +831,57 @@ new_mmap_object(PyObject *self, PyObject *args)
826831 }
827832
828833 m_obj = PyObject_New (mmap_object , & mmap_object_type );
829-
834+ if (m_obj == NULL )
835+ return NULL ;
836+ /* Set every field to an invalid marker, so we can safely
837+ destruct the object in the face of failure */
838+ m_obj -> data = NULL ;
839+ m_obj -> file_handle = (INT_PTR )INVALID_HANDLE_VALUE ;
840+ m_obj -> map_handle = INVALID_HANDLE_VALUE ;
841+ m_obj -> tagname = NULL ;
842+
830843 if (fh ) {
831- m_obj -> file_handle = fh ;
844+ /* It is necessary to duplicate the handle, so the
845+ Python code can close it on us */
846+ if (!DuplicateHandle (
847+ GetCurrentProcess (), /* source process handle */
848+ (HANDLE )fh , /* handle to be duplicated */
849+ GetCurrentProcess (), /* target proc handle */
850+ (LPHANDLE )& m_obj -> file_handle , /* result */
851+ 0 , /* access - ignored due to options value */
852+ FALSE, /* inherited by child processes? */
853+ DUPLICATE_SAME_ACCESS )) { /* options */
854+ dwErr = GetLastError ();
855+ Py_DECREF (m_obj );
856+ PyErr_SetFromWindowsErr (dwErr );
857+ return NULL ;
858+ }
832859 if (!map_size ) {
833860 m_obj -> size = GetFileSize ((HANDLE )fh , NULL );
834861 } else {
835862 m_obj -> size = map_size ;
836863 }
837864 }
838865 else {
839- m_obj -> file_handle = (INT_PTR ) - 1 ;
840866 m_obj -> size = map_size ;
841867 }
842868
843869 /* set the initial position */
844870 m_obj -> pos = (size_t ) 0 ;
845871
872+ /* set the tag name */
873+ if (tagname != NULL ) {
874+ m_obj -> tagname = PyMem_Malloc (strlen (tagname )+ 1 );
875+ if (m_obj -> tagname == NULL ) {
876+ PyErr_NoMemory ();
877+ Py_DECREF (m_obj );
878+ return NULL ;
879+ }
880+ strcpy (m_obj -> tagname , tagname );
881+ }
882+ else
883+ m_obj -> tagname = NULL ;
884+
846885 m_obj -> map_handle = CreateFileMapping ((HANDLE ) m_obj -> file_handle ,
847886 NULL ,
848887 PAGE_READWRITE ,
@@ -863,6 +902,7 @@ new_mmap_object(PyObject *self, PyObject *args)
863902 } else {
864903 dwErr = GetLastError ();
865904 }
905+ Py_DECREF (m_obj );
866906 PyErr_SetFromWindowsErr (dwErr );
867907 return (NULL );
868908}
0 commit comments