Skip to content

Commit ead66d5

Browse files
committed
Fix some mmap errors on POSIX
1 parent 4ff3b33 commit ead66d5

File tree

4 files changed

+30
-23
lines changed

4 files changed

+30
-23
lines changed

Src/IronPython.Modules/mmap.cs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#if FEATURE_MMAP
66

77
using System;
8-
using System.ComponentModel;
98
using System.Diagnostics;
109
using System.Globalization;
1110
using System.IO;
@@ -205,12 +204,12 @@ public static class MmapModule {
205204

206205
public static readonly string __doc__ = null;
207206

208-
private static string FormatError(int errorCode) {
209-
return new Win32Exception(errorCode).Message;
210-
}
211-
212-
private static Exception WindowsError(int code) {
213-
return PythonExceptions.CreateThrowable(PythonExceptions.OSError, code, FormatError(code));
207+
private static Exception WindowsError(int winerror) {
208+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
209+
return PythonNT.GetWin32Error(winerror);
210+
} else {
211+
return PythonNT.GetOsError(PythonExceptions._OSError.WinErrorToErrno(winerror));
212+
}
214213
}
215214

216215
public static PythonType error => PythonExceptions.OSError;
@@ -234,7 +233,7 @@ public MmapUnix(CodeContext/*!*/ context, int fileno, long length, int flags = M
234233
private static MemoryMappedFileAccess ToMmapFileAccess(int flags, int prot, int access) {
235234
if (access == ACCESS_DEFAULT) {
236235
if ((flags & (MAP_PRIVATE | MAP_SHARED)) == 0) {
237-
throw PythonOps.OSError(PythonErrno.EINVAL, "Invalid argument");
236+
throw PythonNT.GetOsError(PythonErrno.EINVAL);
238237
}
239238
if ((prot & PROT_WRITE) != 0) {
240239
prot |= PROT_READ;
@@ -356,7 +355,7 @@ public MmapDefault(CodeContext/*!*/ context, int fileno, long length, string tag
356355
}
357356
// otherwise leaves _file as null and _sourceStream as null
358357
} else {
359-
throw PythonOps.OSError(PythonExceptions._OSError.ERROR_INVALID_BLOCK, "Bad file descriptor");
358+
throw PythonNT.GetOsError(PythonErrno.EBADF);
360359
}
361360

362361
if (_file is null) {
@@ -414,7 +413,7 @@ void CheckFileAccessAndSize(Stream stream, bool isWindows) {
414413

415414
try {
416415
if (!isValid) {
417-
throw PythonOps.OSError(PythonExceptions._OSError.ERROR_ACCESS_DENIED, "Invalid access mode");
416+
throw WindowsError(PythonExceptions._OSError.ERROR_ACCESS_DENIED);
418417
}
419418

420419
if (!isWindows) {
@@ -802,13 +801,21 @@ public void resize(long newsize) {
802801
throw PythonOps.TypeError("mmap can't resize a readonly or copy-on-write memory map.");
803802
}
804803

804+
if (newsize < 0) {
805+
throw PythonOps.ValueError("new size out of range");
806+
}
807+
805808
if (_handle is not null
806809
&& (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux))) {
807810
// resize on Posix platforms
808811
try {
809812
if (_handle.IsInvalid) {
810813
throw PythonNT.GetOsError(PythonErrno.EBADF);
811814
}
815+
if (newsize == 0) {
816+
// resizing to an empty mapped region is not allowed
817+
throw PythonNT.GetOsError(PythonErrno.EINVAL);
818+
}
812819
_view.Flush();
813820
_view.Dispose();
814821
_file.Dispose();

Src/IronPython.Modules/nt.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,8 +2132,9 @@ private static Exception ToPythonException(Exception e, string? filename = null)
21322132
message = e.Message;
21332133
isWindowsError = true;
21342134
} else if (e is UnauthorizedAccessException unauth) {
2135-
errorCode = PythonExceptions._OSError.ERROR_ACCESS_DENIED;
2136-
return PythonOps.OSError(errorCode, "Access is denied", filename, errorCode);
2135+
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
2136+
GetWin32Error(PythonExceptions._OSError.ERROR_ACCESS_DENIED, filename) :
2137+
GetOsError(PythonErrno.EACCES, filename);
21372138
} else {
21382139
var ioe = e as IOException;
21392140
Exception? pe = IOExceptionToPythonException(ioe, error, filename);
@@ -2155,7 +2156,7 @@ private static Exception ToPythonException(Exception e, string? filename = null)
21552156
}
21562157

21572158
if (isWindowsError) {
2158-
return PythonOps.OSError(errorCode, message, filename, errorCode);
2159+
return PythonOps.OSError(PythonExceptions._OSError.WinErrorToErrno(errorCode), message, filename, errorCode);
21592160
}
21602161

21612162
return PythonOps.OSError(errorCode, message, filename);
@@ -2313,8 +2314,8 @@ private static Exception DirectoryExistsError(string? filename) {
23132314
}
23142315

23152316

2316-
internal static Exception GetOsError(int error, string? filename = null, string? filename2 = null)
2317-
=> PythonOps.OSError(error, strerror(error), filename, null, filename2);
2317+
internal static Exception GetOsError(int errno, string? filename = null, string? filename2 = null)
2318+
=> PythonOps.OSError(errno, strerror(errno), filename, null, filename2);
23182319

23192320
#if FEATURE_NATIVE || FEATURE_CTYPES
23202321

@@ -2338,9 +2339,9 @@ private static string GetWin32ErrorMessage(int errorCode) {
23382339
}
23392340

23402341
[SupportedOSPlatform("windows")]
2341-
private static Exception GetWin32Error(int error, string? filename = null, string? filename2 = null) {
2342-
var msg = GetWin32ErrorMessage(error);
2343-
return PythonOps.OSError(0, msg, filename, error, filename2);
2342+
internal static Exception GetWin32Error(int winerror, string? filename = null, string? filename2 = null) {
2343+
var msg = GetWin32ErrorMessage(winerror);
2344+
return PythonOps.OSError(0, msg, filename, winerror, filename2);
23442345
}
23452346

23462347
#endif

Src/IronPython.Modules/resource.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,8 +329,7 @@ private static object LimitsArgError()
329329
=> LightExceptions.Throw(PythonOps.ValueError("expected a tuple of 2 integers"));
330330

331331
private static object GetPInvokeError() {
332-
int errno = Marshal.GetLastWin32Error(); // despite its name, on Posix it retrieves errno set by the last p/Invoke call
333-
return LightExceptions.Throw(PythonOps.OSError(errno, PythonNT.strerror(errno)));
332+
return LightExceptions.Throw(PythonNT.GetLastUnixError());
334333
}
335334

336335
private static object ToPythonInt(this ulong value)

Src/IronPython/Runtime/Exceptions/PythonExceptions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,14 @@ public override void __init__(params object[] args) {
167167
}
168168
if (args.Length >= 4) {
169169
winerror = args[3] ?? Undefined;
170-
if (winerror is int) {
171-
errno = WinErrorToErrno((int)winerror);
170+
if (winerror is int err) {
171+
errno = WinErrorToErrno(err);
172172
}
173173
}
174174
if (args.Length >= 5) {
175175
filename2 = args[4] ?? Undefined;
176176
}
177-
args = new object[] { errno, strerror };
177+
args = [errno, strerror];
178178
}
179179
base.__init__(args);
180180
}

0 commit comments

Comments
 (0)