mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Fix hang when reading stdin from ruby
This is a workaround for a full clr issue that causes a hang when calling PowerShell from ruby. They use named pipes instead of anonymous pipes, and for some reason that triggers the hang.
This commit is contained in:
@@ -3467,6 +3467,9 @@ namespace Microsoft.PowerShell
|
||||
[DllImport(PinvokeDllNames.GetLargestConsoleWindowSizeDllName, SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern COORD GetLargestConsoleWindowSize(NakedWin32Handle consoleOutput);
|
||||
|
||||
[DllImport(PinvokeDllNames.GetStdHandleDllName, SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr GetStdHandle(int handleId);
|
||||
|
||||
[DllImport(PinvokeDllNames.ReadConsoleDllName, SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern bool ReadConsole
|
||||
(
|
||||
|
||||
@@ -2868,6 +2868,25 @@ namespace Microsoft.PowerShell
|
||||
private System.Threading.Thread _breakHandlerThread;
|
||||
private bool _isDisposed;
|
||||
internal ConsoleHostUserInterface ui;
|
||||
|
||||
#if CORECLR
|
||||
internal Lazy<TextReader> ConsoleIn { get; } = new Lazy<TextReader>(() => Console.In);
|
||||
#else
|
||||
internal Lazy<TextReader> ConsoleIn { get; } = new Lazy<TextReader>(() =>
|
||||
{
|
||||
// This is a workaround for a full clr issue that causes a hang when calling PowerShell from ruby.
|
||||
// They use named pipes instead of anonymous pipes, and for some reason that triggers a hang
|
||||
// reading from Console.In.
|
||||
var inputHandle = ConsoleControl.NativeMethods.GetStdHandle(-10);
|
||||
var s = new FileStream(new ConsoleHandle(inputHandle, false), FileAccess.Read);
|
||||
|
||||
uint codePage = (uint) ConsoleControl.NativeMethods.GetConsoleCP();
|
||||
Encoding encoding = Encoding.GetEncoding((int) codePage);
|
||||
|
||||
return TextReader.Synchronized(new StreamReader(s, encoding, false));
|
||||
});
|
||||
#endif
|
||||
|
||||
private string _savedWindowTitle = "";
|
||||
private Version _ver = PSVersionInfo.PSVersion;
|
||||
private int _exitCodeFromRunspace;
|
||||
|
||||
@@ -1560,9 +1560,10 @@ namespace Microsoft.PowerShell
|
||||
sb.Append('\n');
|
||||
}
|
||||
|
||||
var consoleIn = _parent.ConsoleIn.Value;
|
||||
while (true)
|
||||
{
|
||||
var inC = Console.In.Read();
|
||||
var inC = consoleIn.Read();
|
||||
if (inC == -1)
|
||||
{
|
||||
// EOF - we return null which tells our caller to exit
|
||||
@@ -1577,10 +1578,10 @@ namespace Microsoft.PowerShell
|
||||
if (c == '\r')
|
||||
{
|
||||
// Treat as newline, but consume \n if there is one.
|
||||
if (Console.In.Peek() == '\n')
|
||||
if (consoleIn.Peek() == '\n')
|
||||
{
|
||||
if (!NoPrompt) Console.Out.Write('\n');
|
||||
Console.In.Read();
|
||||
consoleIn.Read();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -212,8 +212,7 @@ namespace Microsoft.PowerShell
|
||||
if ((options & ExecutionOptions.ReadInputObjects) > 0 && Console.IsInputRedirected)
|
||||
{
|
||||
// read input objects from stdin
|
||||
|
||||
WrappedDeserializer des = new WrappedDeserializer(_parent.InputFormat, "Input", Console.In);
|
||||
WrappedDeserializer des = new WrappedDeserializer(_parent.InputFormat, "Input", _parent.ConsoleIn.Value);
|
||||
while (!des.AtEnd)
|
||||
{
|
||||
object o = des.Deserialize();
|
||||
|
||||
Reference in New Issue
Block a user