Skip to content

Commit d7fc0e3

Browse files

File tree

5 files changed

+75
-49
lines changed

5 files changed

+75
-49
lines changed

Src/IronPython.Modules/msvcrt.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using System.IO;
2121
using System.IO.Pipes;
2222
using System.Runtime.InteropServices;
23+
using Microsoft.Win32.SafeHandles;
2324

2425
using Microsoft.Scripting.Runtime;
2526

@@ -60,9 +61,7 @@ to os.fdopen() to create a file object.
6061
")]
6162

6263
public static int open_osfhandle(CodeContext context, BigInteger os_handle, int arg1) {
63-
#pragma warning disable 618 // System.IO.FileStream.FileStream(System.IntPtr, System.IO.FileAccess, bool) is obsolete
64-
FileStream stream = new FileStream(new IntPtr((long)os_handle), FileAccess.ReadWrite, true);
65-
#pragma warning restore 618
64+
FileStream stream = new FileStream(new SafeFileHandle(new IntPtr((long)os_handle), true), FileAccess.ReadWrite);
6665
return context.LanguageContext.FileManager.AddToStrongMapping(stream);
6766
}
6867

@@ -73,13 +72,9 @@ public static int open_osfhandle(CodeContext context, BigInteger os_handle, int
7372
public static object get_osfhandle(CodeContext context, int fd) {
7473
PythonFile pfile = context.LanguageContext.FileManager.GetFileFromId(context.LanguageContext, fd);
7574

76-
Stream stream = pfile._stream;
77-
if (stream is FileStream) {
78-
return ((FileStream)stream).SafeFileHandle.DangerousGetHandle().ToPython();
79-
}
80-
if (stream is PipeStream) {
81-
return ((PipeStream)stream).SafePipeHandle.DangerousGetHandle().ToPython();
82-
}
75+
object handle;
76+
if (pfile.TryGetFileHandle(out handle)) return handle;
77+
8378
return -1;
8479
}
8580

Src/IronPython.Modules/nt.cs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ public static int getpid() {
358358

359359
public static List listdir(CodeContext/*!*/ context, [NotNull]string path) {
360360
if (path == String.Empty) {
361-
path = ".";
361+
throw PythonExceptions.CreateThrowable(WindowsError, PythonExceptions._OSError.ERROR_PATH_NOT_FOUND, "The system cannot find the path specified: ''", null, PythonExceptions._OSError.ERROR_PATH_NOT_FOUND);
362362
}
363363

364364
List ret = PythonOps.MakeList();
@@ -792,7 +792,6 @@ public static void startfile(string filename, string operation="open") {
792792
process.StartInfo.UseShellExecute = true;
793793
process.StartInfo.Verb = operation;
794794
try {
795-
796795
process.Start();
797796
} catch (Exception e) {
798797
throw ToPythonException(e, filename);
@@ -994,7 +993,17 @@ public object st_uid {
994993
}
995994

996995
public override string ToString() {
997-
return MakeTuple().ToString();
996+
return string.Format("nt.stat_result("
997+
+ "st_mode={0}, "
998+
+ "st_ino={1}, "
999+
+ "st_dev={2}, "
1000+
+ "st_nlink={3}, "
1001+
+ "st_uid={4}, "
1002+
+ "st_gid={5}, "
1003+
+ "st_size={6}, "
1004+
+ "st_atime={7}, "
1005+
+ "st_mtime={8}, "
1006+
+ "st_ctime={9})", MakeTuple().ToArray());
9981007
}
9991008

10001009
public string/*!*/ __repr__() {
@@ -1423,6 +1432,14 @@ public static int umask(CodeContext/*!*/ context, int mask) {
14231432
}
14241433
}
14251434

1435+
public static int umask(CodeContext/*!*/ context, BigInteger mask) {
1436+
return umask(context, (int)mask);
1437+
}
1438+
1439+
public static int umask(double mask) {
1440+
throw PythonOps.TypeError("integer argument expected, got float");
1441+
}
1442+
14261443
#if FEATURE_FILESYSTEM
14271444
public static void utime(string path, PythonTuple times) {
14281445
try {
@@ -1469,7 +1486,7 @@ public static PythonTuple waitpid(int pid, object options) {
14691486
}
14701487
#endif
14711488

1472-
public static int write(CodeContext/*!*/ context, int fd, string text) {
1489+
public static int write(CodeContext/*!*/ context, int fd, [BytesConversion]string text) {
14731490
try {
14741491
PythonContext pythonContext = PythonContext.GetContext(context);
14751492
PythonFile pf = pythonContext.FileManager.GetFileFromId(pythonContext, fd);
@@ -1484,6 +1501,8 @@ public static int write(CodeContext/*!*/ context, int fd, string text) {
14841501
[Documentation(@"Send signal sig to the process pid. Constants for the specific signals available on the host platform
14851502
are defined in the signal module.")]
14861503
public static void kill(CodeContext/*!*/ context, int pid, int sig) {
1504+
if (PythonSignal.NativeSignal.GenerateConsoleCtrlEvent((uint)sig, (uint)pid)) return;
1505+
14871506
//If the calls to GenerateConsoleCtrlEvent didn't work, simply
14881507
//forcefully kill the process.
14891508
Process toKill = Process.GetProcessById(pid);

Src/IronPython/Modules/_fileio.cs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,19 @@ public FileIO(CodeContext/*!*/ context, int fd, string mode="r", bool closefd=tr
112112
_readStream = pythonFile._stream;
113113
}
114114
else {
115-
FileIO file = (FileIO)pc.FileManager.GetObjectFromId(fd);
116-
name = file.name ?? fd;
117-
_readStream = file._readStream;
118-
_writeStream = file._writeStream;
115+
object obj = pc.FileManager.GetObjectFromId(fd);
116+
if (obj is FileIO) {
117+
FileIO file = (FileIO)obj;
118+
name = file.name ?? fd;
119+
_readStream = file._readStream;
120+
_writeStream = file._writeStream;
121+
}
122+
else if (obj is Stream) {
123+
Stream stream = (Stream)obj;
124+
name = fd;
125+
_readStream = stream;
126+
_writeStream = stream;
127+
}
119128
}
120129

121130
_closefd = closefd;
@@ -281,7 +290,9 @@ public override int fileno(CodeContext/*!*/ context) {
281290
public override void flush(CodeContext/*!*/ context) {
282291
_checkClosed();
283292

284-
_writeStream.Flush();
293+
if (_writeStream != null) {
294+
_writeStream.Flush();
295+
}
285296
}
286297

287298
[Documentation("isatty() -> bool. True if the file is connected to a tty device.")]

Src/IronPython/Runtime/PythonFile.cs

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
using System.ComponentModel;
2020
using System.Diagnostics;
2121
using System.IO;
22+
using System.Reflection;
2223
using System.Runtime.InteropServices;
2324
using System.Text;
2425
using System.Threading;
@@ -37,7 +38,6 @@
3738

3839
#if FEATURE_NUMERICS
3940
using System.Numerics;
40-
4141
#else
4242
using Microsoft.Scripting.Math;
4343
#endif
@@ -1083,32 +1083,23 @@ public PythonFile(CodeContext/*!*/ context)
10831083
}
10841084

10851085
#if FEATURE_PROCESS
1086-
internal static PythonFile[] CreatePipe(CodeContext/*!*/ context, SafePipeHandle hRead, SafePipeHandle hWrite) {
1086+
internal static PythonFile[] CreatePipe(CodeContext/*!*/ context) {
10871087
var pythonContext = PythonContext.GetContext(context);
10881088
var encoding = pythonContext.DefaultEncoding;
10891089

1090-
var inPipe = new AnonymousPipeStream(PipeDirection.In, hRead);
1090+
var inPipe = new AnonymousPipeServerStream(PipeDirection.In);
10911091
var inPipeFile = new PythonFile(context);
10921092
inPipeFile.InitializePipe(inPipe, "r", encoding);
10931093

1094-
var outPipe = new AnonymousPipeStream(PipeDirection.Out, hWrite);
1094+
var outPipe = new AnonymousPipeClientStream(PipeDirection.Out, inPipe.ClientSafePipeHandle);
10951095
var outPipeFile = new PythonFile(context);
10961096
outPipeFile.InitializePipe(outPipe, "w", encoding);
10971097
return new [] {inPipeFile, outPipeFile};
10981098
}
10991099

11001100
[PythonHidden]
11011101
public static PythonTuple CreatePipeAsFd(CodeContext context) {
1102-
SafePipeHandle hRead, hWrite;
1103-
var secAttrs = new NativeMethods.SECURITY_ATTRIBUTES();
1104-
secAttrs.nLength = Marshal.SizeOf(secAttrs);
1105-
1106-
if (!NativeMethods.CreatePipe(out hRead, out hWrite, ref secAttrs, 0)) {
1107-
var err = Marshal.GetLastWin32Error();
1108-
throw PythonExceptions.CreateThrowable(PythonExceptions.OSError, err,
1109-
new Win32Exception(err).Message, null, err);
1110-
}
1111-
var pipeFiles = CreatePipe(context, hRead, hWrite);
1102+
var pipeFiles = CreatePipe(context);
11121103
return PythonTuple.MakeTuple(
11131104
PythonContext.GetContext(context).FileManager.AddToStrongMapping(pipeFiles[0]),
11141105
PythonContext.GetContext(context).FileManager.AddToStrongMapping(pipeFiles[1]));
@@ -1310,7 +1301,7 @@ public void __init__([NotNull]Stream/*!*/ stream, [NotNull]Encoding/*!*/ encodin
13101301
return new PythonTextWriter(writer, "\r");
13111302

13121303
case PythonFileMode.TextLf:
1313-
return new PythonTextWriter(writer, null);
1304+
return new PythonTextWriter(writer, "\n");
13141305
}
13151306

13161307
throw Assert.Unreachable;
@@ -1409,6 +1400,31 @@ internal void InternalInitialize(Stream stream, Encoding encoding, string name,
14091400

14101401
#endregion
14111402

1403+
#if !SILVERLIGHT
1404+
internal bool TryGetFileHandle(out object handle) {
1405+
Stream stream = _stream;
1406+
1407+
if (stream is FileStream) {
1408+
handle = ((FileStream)stream).SafeFileHandle.DangerousGetHandle().ToPython();
1409+
return true;
1410+
}
1411+
if (stream is PipeStream) {
1412+
handle = ((PipeStream)stream).SafePipeHandle.DangerousGetHandle().ToPython();
1413+
return true;
1414+
}
1415+
1416+
// if all else fails try reflection
1417+
var sfh = stream.GetType().GetField("_handle", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(stream);
1418+
if (sfh is SafeFileHandle) {
1419+
handle = ((SafeFileHandle)sfh).DangerousGetHandle().ToPython();
1420+
return true;
1421+
}
1422+
1423+
handle = null;
1424+
return false;
1425+
}
1426+
#endif
1427+
14121428
// Enumeration of each stream mode.
14131429
private enum PythonFileMode {
14141430
Binary,
@@ -1942,16 +1958,6 @@ void IEnumerator.Reset() {
19421958
#endregion
19431959
}
19441960

1945-
#if FEATURE_PROCESS
1946-
internal class AnonymousPipeStream : PipeStream {
1947-
public AnonymousPipeStream(PipeDirection direction, SafePipeHandle sph) : base(direction, 0) {
1948-
InitializeHandle(sph, true, false);
1949-
IsConnected = true;
1950-
}
1951-
}
1952-
#endif
1953-
1954-
19551961
#if FEATURE_NATIVE && !CLR45
19561962
// dotnet45 backport
19571963
// http://msdn.microsoft.com/en-us/library/system.console.isoutputredirected%28v=VS.110%29.aspx

Src/IronPython/Runtime/Win32Native.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,6 @@ internal static extern bool FindNextFile(
5858
public int bInheritHandle;
5959
}
6060

61-
[DllImport("kernel32.dll")]
62-
[return: MarshalAs(UnmanagedType.Bool)]
63-
internal static extern bool CreatePipe(out SafePipeHandle hReadPipe, out SafePipeHandle hWritePipe,
64-
ref SECURITY_ATTRIBUTES lpPipeAttributes, uint nSize);
65-
6661
[DllImport("kernel32.dll", SetLastError=true)]
6762
[return: MarshalAs(UnmanagedType.Bool)]
6863
internal static extern bool FlushFileBuffers(SafeFileHandle hFile);

0 commit comments

Comments
 (0)