-
Notifications
You must be signed in to change notification settings - Fork 306
Isolate POSIX-specific native calls in PythonNT into separate file #1870
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
fcc8db8
9035d36
17eb367
4ff3b33
ead66d5
7113ba3
6e409b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -339,13 +339,13 @@ public MmapDefault(CodeContext/*!*/ context, int fileno, long length, string tag | |
| #if NET8_0_OR_GREATER | ||
| // On .NET 8.0+ we can create a MemoryMappedFile directly from a file descriptor | ||
| stream.Flush(); | ||
| CheckFileAccessAndSize(stream); | ||
| fileno = Dup(fileno); | ||
| CheckFileAccessAndSize(stream, isWindows: false); | ||
| fileno = PythonNT.dupUnix(fileno, closeOnExec: true); | ||
| _handle = new SafeFileHandle((IntPtr)fileno, ownsHandle: true); | ||
| _file = MemoryMappedFile.CreateFromFile(_handle, _mapName, stream.Length, _fileAccess, HandleInheritability.None, leaveOpen: true); | ||
| #else | ||
| // On .NET 6.0 on POSIX we need to create a FileStream from the file descriptor | ||
| fileno = Dup(fileno); | ||
| fileno = PythonNT.dupUnix(fileno, closeOnExec: true); | ||
| _handle = new SafeFileHandle((IntPtr)fileno, ownsHandle: true); | ||
| FileAccess fa = stream.CanWrite ? stream.CanRead ? FileAccess.ReadWrite : FileAccess.Write : FileAccess.Read; | ||
| // This FileStream constructor may or may not work on Mono, but on Mono streams.ReadStream is FileStream | ||
|
|
@@ -369,7 +369,7 @@ public MmapDefault(CodeContext/*!*/ context, int fileno, long length, string tag | |
| length = _sourceStream.Length - _offset; | ||
| } | ||
|
|
||
| CheckFileAccessAndSize(_sourceStream); | ||
| CheckFileAccessAndSize(_sourceStream, RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); | ||
|
|
||
| long capacity = checked(_offset + length); | ||
|
|
||
|
|
@@ -402,7 +402,7 @@ public MmapDefault(CodeContext/*!*/ context, int fileno, long length, string tag | |
| } | ||
| _position = 0L; | ||
|
|
||
| void CheckFileAccessAndSize(Stream stream) { | ||
| void CheckFileAccessAndSize(Stream stream, bool isWindows) { | ||
| bool isValid = _fileAccess switch { | ||
| MemoryMappedFileAccess.Read => stream.CanRead, | ||
| MemoryMappedFileAccess.ReadWrite => stream.CanRead && stream.CanWrite, | ||
|
|
@@ -417,7 +417,7 @@ void CheckFileAccessAndSize(Stream stream) { | |
| throw PythonOps.OSError(PythonExceptions._OSError.ERROR_ACCESS_DENIED, "Invalid access mode"); | ||
| } | ||
|
|
||
| if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { | ||
| if (!isWindows) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not really an issue since we're not calling native APIs here, but any idea if the platform analyzer would pick up on an
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As it is written now, no platform-specific calls are allowed in The reason why I replaced the platform check with a parameter is because having the platform test in this function was invalidating the platform context after the first call site, and I needed to make a call to
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool, didn't know (or forgot) that Weird that iy breaks the platform check. Alternatively the parameter could be called |
||
| // Unix map does not support increasing size on open | ||
| if (length != 0 && _offset + length > stream.Length) { | ||
| throw PythonOps.ValueError("mmap length is greater than file size"); | ||
|
|
@@ -437,29 +437,6 @@ void CheckFileAccessAndSize(Stream stream) { | |
| } // end of constructor | ||
|
|
||
|
|
||
| // TODO: Move to PythonNT - POSIX | ||
| private static int Dup(int fd) { | ||
| int fd2 = Mono.Unix.Native.Syscall.dup(fd); | ||
| if (fd2 == -1) throw PythonNT.GetLastUnixError(); | ||
|
|
||
| try { | ||
| // set close-on-exec flag | ||
| int flags = Mono.Unix.Native.Syscall.fcntl(fd2, Mono.Unix.Native.FcntlCommand.F_GETFD); | ||
| if (flags == -1) throw PythonNT.GetLastUnixError(); | ||
|
|
||
| const int FD_CLOEXEC = 1; // TODO: Move to module fcntl | ||
| flags |= FD_CLOEXEC; | ||
| flags = Mono.Unix.Native.Syscall.fcntl(fd2, Mono.Unix.Native.FcntlCommand.F_SETFD, flags); | ||
| if (flags == -1) throw PythonNT.GetLastUnixError(); | ||
| } catch { | ||
| Mono.Unix.Native.Syscall.close(fd2); | ||
| throw; | ||
| } | ||
|
|
||
| return fd2; | ||
| } | ||
|
|
||
|
|
||
| public object __len__() { | ||
| using (new MmapLocker(this)) { | ||
| return ReturnLong(_view.Capacity); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the attribute on both the class and method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it's redundant.