2828[ assembly: PythonModule ( "mmap" , typeof ( IronPython . Modules . MmapModule ) ) ]
2929namespace IronPython . Modules {
3030 public static class MmapModule {
31+ public const int ACCESS_DEFAULT = 0 ; // Since Python 3.7
3132 public const int ACCESS_READ = 1 ;
3233 public const int ACCESS_WRITE = 2 ;
3334 public const int ACCESS_COPY = 3 ;
@@ -42,8 +43,6 @@ public static class MmapModule {
4243 [ PythonHidden ( PlatformsAttribute . PlatformFamily . Windows ) ]
4344 public const int MAP_PRIVATE = 2 ;
4445
45- [ PythonHidden ( PlatformsAttribute . PlatformFamily . Windows ) ]
46- public const int PROT_NONE = 0 ;
4746 [ PythonHidden ( PlatformsAttribute . PlatformFamily . Windows ) ]
4847 public const int PROT_READ = 1 ;
4948 [ PythonHidden ( PlatformsAttribute . PlatformFamily . Windows ) ]
@@ -78,8 +77,28 @@ public static PythonType mmap {
7877
7978 [ PythonType ( "mmap" ) , PythonHidden ]
8079 public class MmapUnix : MmapDefault {
81- public MmapUnix ( CodeContext /*!*/ context , int fileno , long length , int flags = MAP_SHARED , int prot = PROT_WRITE | PROT_READ , int access = ACCESS_WRITE , long offset = 0 )
82- : base ( context , fileno , length , null , access , offset ) { }
80+ public MmapUnix ( CodeContext /*!*/ context , int fileno , long length , int flags = MAP_SHARED , int prot = PROT_WRITE | PROT_READ , int access = ACCESS_DEFAULT , long offset = 0 )
81+ : base ( context , fileno , length , null , NormalizeAccess ( flags , prot , access ) , offset ) { }
82+
83+ private static int NormalizeAccess ( int flags , int prot , int access ) {
84+ if ( access == ACCESS_DEFAULT ) {
85+ if ( ( flags & ( MAP_PRIVATE | MAP_SHARED ) ) == 0 ) {
86+ throw PythonOps . OSError ( PythonErrorNumber . EINVAL , "Invalid argument" ) ;
87+ }
88+ if ( ( prot & PROT_WRITE ) != 0 ) {
89+ return ( flags & MAP_PRIVATE ) != 0 ? ACCESS_COPY : ACCESS_WRITE ;
90+ }
91+ if ( ( prot & PROT_READ ) != 0 ) {
92+ return ACCESS_READ ;
93+ }
94+ throw PythonOps . NotImplementedError ( "this combination of flags and prot is not supported" ) ;
95+ } else if ( flags != MAP_SHARED || prot != ( PROT_WRITE | PROT_READ ) ) {
96+ throw PythonOps . ValueError ( "mmap can't specify both access and flags, prot." ) ;
97+ } else if ( access != ACCESS_READ && access != ACCESS_WRITE && access != ACCESS_COPY ) {
98+ throw PythonOps . ValueError ( "mmap invalid access parameter" ) ;
99+ }
100+ return access ;
101+ }
83102 }
84103
85104 [ PythonType ( "mmap" ) , PythonHidden ]
@@ -96,11 +115,12 @@ public class MmapDefault : IWeakReferenceable {
96115 private volatile bool _isClosed ;
97116 private int _refCount = 1 ;
98117
99- public MmapDefault ( CodeContext /*!*/ context , int fileno , long length , string tagname = null , int access = ACCESS_WRITE , long offset = 0 ) {
118+ public MmapDefault ( CodeContext /*!*/ context , int fileno , long length , string tagname = null , int access = ACCESS_DEFAULT , long offset = 0 ) {
100119 switch ( access ) {
101120 case ACCESS_READ :
102121 _fileAccess = MemoryMappedFileAccess . Read ;
103122 break ;
123+ case ACCESS_DEFAULT : // On Windows, default access is write-through
104124 case ACCESS_WRITE :
105125 _fileAccess = MemoryMappedFileAccess . ReadWrite ;
106126 break ;
@@ -170,6 +190,13 @@ public MmapDefault(CodeContext/*!*/ context, int fileno, long length, string tag
170190 length -= _offset ;
171191 }
172192
193+ if ( ! RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ) {
194+ // Unix map does not support increasing size on open
195+ if ( _offset + length > _sourceStream . Length ) {
196+ throw PythonOps . ValueError ( "mmap length is greater than file size" ) ;
197+ }
198+ }
199+
173200 long capacity = checked ( _offset + length ) ;
174201
175202 // Enlarge the file as needed.
0 commit comments