3636
3737[ assembly: PythonModule ( "nt" , typeof ( IronPython . Modules . PythonNT ) ) ]
3838namespace IronPython . Modules {
39- public static class PythonNT {
39+ public static partial class PythonNT {
4040 public const string __doc__ = "Provides low-level operating system access for files, the environment, etc..." ;
4141
4242 /* TODO: missing functions/classes:
@@ -301,12 +301,6 @@ public static void chdir(CodeContext context, [NotNone] Bytes path)
301301 public static void chdir ( CodeContext context , object ? path )
302302 => chdir ( ConvertToFsString ( context , path , nameof ( path ) ) ) ;
303303
304- // Isolate Mono.Unix from the rest of the method so that we don't try to load the Mono.Unix assembly on Windows.
305- private static void chmodUnix ( string path , int mode ) {
306- if ( Mono . Unix . Native . Syscall . chmod ( path , Mono . Unix . Native . NativeConvert . ToFilePermissions ( ( uint ) mode ) ) == 0 ) return ;
307- throw GetLastUnixError ( path ) ;
308- }
309-
310304 [ Documentation ( "chmod(path, mode, *, dir_fd=None, follow_symlinks=True)" ) ]
311305 public static void chmod ( [ NotNone ] string path , int mode , [ ParamDictionary , NotNone ] IDictionary < string , object > kwargs ) {
312306 foreach ( var key in kwargs . Keys ) {
@@ -371,7 +365,7 @@ public static int dup(CodeContext/*!*/ context, int fd) {
371365
372366 StreamBox streams = fileManager . GetStreams ( fd ) ; // OSError if fd not valid
373367 if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) || RuntimeInformation . IsOSPlatform ( OSPlatform . OSX ) ) {
374- int fd2 = UnixDup ( fd , - 1 , out Stream ? dupstream ) ;
368+ int fd2 = DuplicateStreamDescriptorUnix ( fd , - 1 , out Stream ? dupstream ) ;
375369 if ( dupstream is not null ) {
376370 return fileManager . Add ( fd2 , new ( dupstream ) ) ;
377371 } else {
@@ -413,7 +407,7 @@ public static int dup2(CodeContext/*!*/ context, int fd, int fd2) {
413407 fd = fs . SafeFileHandle . DangerousGetHandle ( ) . ToInt32 ( ) ;
414408 fs . Seek ( pos , SeekOrigin . Begin ) ;
415409 }
416- fd2 = UnixDup ( fd , fd2 , out Stream ? dupstream ) ; // closes fd2 atomically if reopened in the meantime
410+ fd2 = DuplicateStreamDescriptorUnix ( fd , fd2 , out Stream ? dupstream ) ; // closes fd2 atomically if reopened in the meantime
417411 fileManager . Remove ( fd2 ) ;
418412 if ( dupstream is not null ) {
419413 return fileManager . Add ( fd2 , new ( dupstream ) ) ;
@@ -431,41 +425,6 @@ public static int dup2(CodeContext/*!*/ context, int fd, int fd2) {
431425 }
432426
433427
434- [ SupportedOSPlatform ( "linux" ) , SupportedOSPlatform ( "osx" ) ]
435- private static int UnixDup ( int fd , int fd2 , out Stream ? stream ) {
436- int res = fd2 < 0 ? Mono . Unix . Native . Syscall . dup ( fd ) : Mono . Unix . Native . Syscall . dup2 ( fd , fd2 ) ;
437- if ( res < 0 ) throw GetLastUnixError ( ) ;
438- if ( ClrModule . IsMono ) {
439- // Elaborate workaround on Mono to avoid UnixStream as out
440- stream = new Mono . Unix . UnixStream ( res , ownsHandle : false ) ;
441- FileAccess fileAccess = stream . CanWrite ? stream . CanRead ? FileAccess . ReadWrite : FileAccess . Write : FileAccess . Read ;
442- stream . Dispose ( ) ;
443- try {
444- // FileStream on Mono created with a file descriptor might not work: https://github.com/mono/mono/issues/12783
445- // Test if it does, without closing the handle if it doesn't
446- var sfh = new SafeFileHandle ( ( IntPtr ) res , ownsHandle : false ) ;
447- stream = new FileStream ( sfh , fileAccess ) ;
448- // No exception? Great! We can use FileStream.
449- stream . Dispose ( ) ;
450- sfh . Dispose ( ) ;
451- stream = null ; // Create outside of try block
452- } catch ( IOException ) {
453- // Fall back to UnixStream
454- stream = new Mono . Unix . UnixStream ( res , ownsHandle : true ) ;
455- }
456- if ( stream is null ) {
457- // FileStream is safe
458- var sfh = new SafeFileHandle ( ( IntPtr ) res , ownsHandle : true ) ;
459- stream = new FileStream ( sfh , fileAccess ) ;
460- }
461- } else {
462- // normal case
463- stream = new PosixFileStream ( res ) ;
464- }
465- return res ;
466- }
467-
468-
469428#if FEATURE_PROCESS
470429 /// <summary>
471430 /// single instance of environment dictionary is shared between multiple runtimes because the environment
@@ -563,11 +522,6 @@ static void linkWindows(string src, string dst) {
563522 if ( ! CreateHardLink ( dst , src , IntPtr . Zero ) )
564523 throw GetLastWin32Error ( src , dst ) ;
565524 }
566-
567- static void linkUnix ( string src , string dst ) {
568- if ( Mono . Unix . Native . Syscall . link ( src , dst ) == 0 ) return ;
569- throw GetLastUnixError ( src , dst ) ;
570- }
571525 }
572526
573527 public static bool isatty ( CodeContext context , int fd ) {
@@ -779,11 +733,6 @@ public static void symlink([NotNone] string src, [NotNone] string dst, [ParamDic
779733 } else {
780734 throw new NotImplementedException ( ) ;
781735 }
782-
783- static void symlinkUnix ( string src , string dst ) {
784- if ( Mono . Unix . Native . Syscall . symlink ( src , dst ) == 0 ) return ;
785- throw GetLastUnixError ( src , dst ) ;
786- }
787736 }
788737
789738 [ Documentation ( "" ) ]
@@ -1012,17 +961,14 @@ public static PythonTuple pipe(CodeContext context) {
1012961 manager . Add ( new ( inPipe ) ) ,
1013962 manager . Add ( new ( outPipe ) )
1014963 ) ;
1015- } else {
964+ } else if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) || RuntimeInformation . IsOSPlatform ( OSPlatform . OSX ) ) {
1016965 var pipeStreams = CreatePipeStreamsUnix ( ) ;
1017966 return PythonTuple . MakeTuple (
1018967 manager . Add ( pipeStreams . Item1 , new ( pipeStreams . Item2 ) ) ,
1019968 manager . Add ( pipeStreams . Item3 , new ( pipeStreams . Item4 ) )
1020969 ) ;
1021- }
1022-
1023- static Tuple < int , Stream , int , Stream > CreatePipeStreamsUnix ( ) {
1024- Mono . Unix . UnixPipes pipes = Mono . Unix . UnixPipes . CreatePipes ( ) ;
1025- return Tuple . Create < int , Stream , int , Stream > ( pipes . Reading . Handle , pipes . Reading , pipes . Writing . Handle , pipes . Writing ) ;
970+ } else {
971+ throw new PlatformNotSupportedException ( ) ;
1026972 }
1027973 }
1028974#endif
@@ -1094,11 +1040,6 @@ public static void rename(CodeContext context, object? src, object? dst, [ParamD
10941040 [ DllImport ( "kernel32.dll" , EntryPoint = "MoveFileExW" , SetLastError = true , CharSet = CharSet . Unicode , BestFitMapping = false ) ]
10951041 private static extern bool MoveFileEx ( string src , string dst , uint flags ) ;
10961042
1097- private static void renameUnix ( string src , string dst ) {
1098- if ( Mono . Unix . Native . Syscall . rename ( src , dst ) == 0 ) return ;
1099- throw GetLastUnixError ( src , dst ) ;
1100- }
1101-
11021043 [ Documentation ( "replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)" ) ]
11031044 public static void replace ( [ NotNone ] string src , [ NotNone ] string dst , [ ParamDictionary , NotNone ] IDictionary < string , object > kwargs ) {
11041045 foreach ( var key in kwargs . Keys ) {
@@ -1467,21 +1408,6 @@ private static bool HasExecutableExtension(string path) {
14671408 return ( extension == ".exe" || extension == ".dll" || extension == ".com" || extension == ".bat" ) ;
14681409 }
14691410
1470- // Isolate Mono.Unix from the rest of the method so that we don't try to load the Mono.Unix assembly on Windows.
1471- private static object statUnix ( string path ) {
1472- if ( Mono . Unix . Native . Syscall . stat ( path , out Mono . Unix . Native . Stat buf ) == 0 ) {
1473- return new stat_result ( buf ) ;
1474- }
1475- return LightExceptions . Throw ( GetLastUnixError ( path ) ) ;
1476- }
1477-
1478- private static object fstatUnix ( int fd ) {
1479- if ( Mono . Unix . Native . Syscall . fstat ( fd , out Mono . Unix . Native . Stat buf ) == 0 ) {
1480- return new stat_result ( buf ) ;
1481- }
1482- return LightExceptions . Throw ( GetLastUnixError ( ) ) ;
1483- }
1484-
14851411 private const int OPEN_EXISTING = 3 ;
14861412 private const int FILE_ATTRIBUTE_NORMAL = 0x00000080 ;
14871413 private const int FILE_READ_ATTRIBUTES = 0x0080 ;
@@ -1616,9 +1542,12 @@ public static string strerror(int code) {
16161542 const int bufsize = 0x1FF ;
16171543 var buffer = new StringBuilder ( bufsize ) ;
16181544
1619- int result = RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ?
1620- Interop . Ucrtbase . strerror ( code , buffer ) :
1621- strerror_r ( code , buffer ) ;
1545+ int result = - 1 ;
1546+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ) {
1547+ result = Interop . Ucrtbase . strerror ( code , buffer ) ;
1548+ } else if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) || RuntimeInformation . IsOSPlatform ( OSPlatform . OSX ) ) {
1549+ result = strerror_r ( code , buffer ) ;
1550+ }
16221551
16231552 if ( result == 0 ) {
16241553 var msg = buffer . ToString ( ) ;
@@ -1630,12 +1559,6 @@ public static string strerror(int code) {
16301559 return "Unknown error " + code ;
16311560 }
16321561
1633- #if FEATURE_NATIVE
1634- // Isolate Mono.Unix from the rest of the method so that we don't try to load the Mono.Unix assembly on Windows.
1635- private static int strerror_r ( int code , StringBuilder buffer )
1636- => Mono . Unix . Native . Syscall . strerror_r ( Mono . Unix . Native . NativeConvert . ToErrno ( code ) , buffer ) ;
1637- #endif
1638-
16391562#if FEATURE_PROCESS
16401563 [ Documentation ( "system(command) -> int\n Execute the command (a string) in a subshell." ) ]
16411564 public static int system ( [ NotNone ] string command ) {
@@ -1724,18 +1647,6 @@ public static void ftruncate(CodeContext context, int fd, BigInteger length) {
17241647 }
17251648
17261649
1727- [ SupportedOSPlatform ( "linux" ) , SupportedOSPlatform ( "osx" ) ]
1728- internal static void ftruncateUnix ( int fd , long length ) {
1729- int result ;
1730- Mono . Unix . Native . Errno errno ;
1731- do {
1732- result = Mono . Unix . Native . Syscall . ftruncate ( fd , length ) ;
1733- } while ( Mono . Unix . UnixMarshal . ShouldRetrySyscall ( result , out errno ) ) ;
1734-
1735- if ( errno != 0 )
1736- throw GetOsError ( Mono . Unix . Native . NativeConvert . FromErrno ( errno ) ) ;
1737- }
1738-
17391650
17401651#if FEATURE_FILESYSTEM
17411652 public static object times ( ) {
@@ -1841,18 +1752,6 @@ public static int umask(CodeContext/*!*/ context, object? mask)
18411752
18421753#if FEATURE_FILESYSTEM
18431754
1844- private static void utimeUnix ( string path , long atime_ns , long utime_ns ) {
1845- var atime = new Mono . Unix . Native . Timespec ( ) ;
1846- atime . tv_sec = atime_ns / 1_000_000_000 ;
1847- atime . tv_nsec = atime_ns % 1_000_000_000 ;
1848- var utime = new Mono . Unix . Native . Timespec ( ) ;
1849- utime . tv_sec = utime_ns / 1_000_000_000 ;
1850- utime . tv_nsec = utime_ns % 1_000_000_000 ;
1851-
1852- if ( Mono . Unix . Native . Syscall . utimensat ( Mono . Unix . Native . Syscall . AT_FDCWD , path , new [ ] { atime , utime } , 0 ) == 0 ) return ;
1853- throw GetLastUnixError ( path ) ;
1854- }
1855-
18561755 [ Documentation ( "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)" ) ]
18571756 public static void utime ( [ NotNone ] string path , [ ParamDictionary , NotNone ] IDictionary < string , object > kwargs , [ NotNone ] params object [ ] args ) {
18581757 var numArgs = args . Length ;
@@ -1979,8 +1878,7 @@ public static int write(CodeContext/*!*/ context, int fd, [NotNone] IBufferProto
19791878 public static void kill ( CodeContext /*!*/ context , int pid , int sig ) {
19801879 if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) ||
19811880 RuntimeInformation . IsOSPlatform ( OSPlatform . OSX ) ) {
1982- if ( Mono . Unix . Native . Syscall . kill ( pid , Mono . Unix . Native . NativeConvert . ToSignum ( sig ) ) == 0 ) return ;
1983- throw GetLastUnixError ( ) ;
1881+ killUnix ( pid , sig ) ;
19841882 } else {
19851883 if ( PythonSignal . NativeSignal . GenerateConsoleCtrlEvent ( ( uint ) sig , ( uint ) pid ) ) return ;
19861884
@@ -2414,12 +2312,6 @@ private static Exception DirectoryExistsError(string? filename) {
24142312 return GetOsError ( PythonErrno . EEXIST , filename ) ;
24152313 }
24162314
2417- #if FEATURE_NATIVE
2418-
2419- internal static Exception GetLastUnixError ( string ? filename = null , string ? filename2 = null )
2420- => GetOsError ( Mono . Unix . Native . NativeConvert . FromErrno ( Mono . Unix . Native . Syscall . GetLastError ( ) ) , filename , filename2 ) ;
2421-
2422- #endif
24232315
24242316 private static Exception GetOsError ( int error , string ? filename = null , string ? filename2 = null )
24252317 => PythonOps . OSError ( error , strerror ( error ) , filename , null , filename2 ) ;
0 commit comments