From b505970218ccbd7806835838a2c3d85cbc42a98a Mon Sep 17 00:00:00 2001 From: asmichi Date: Sun, 22 Sep 2024 16:38:52 +0900 Subject: [PATCH] Fix more undisposed handles --- .../PlatformAbstraction/ConsolePal.cs | 18 ++++++--- .../Unix/UnixConsolePal.cs | 12 +++--- .../Windows/WindowsConsolePal.cs | 12 +++--- .../PipelineStdHandleCreator.cs | 39 +++++++++++++++++-- 4 files changed, 60 insertions(+), 21 deletions(-) diff --git a/src/ChildProcess/PlatformAbstraction/ConsolePal.cs b/src/ChildProcess/PlatformAbstraction/ConsolePal.cs index 9eaeefb..4a4953c 100644 --- a/src/ChildProcess/PlatformAbstraction/ConsolePal.cs +++ b/src/ChildProcess/PlatformAbstraction/ConsolePal.cs @@ -7,9 +7,9 @@ namespace Asmichi.PlatformAbstraction { internal interface IConsolePal { - SafeFileHandle GetStdInputHandleForChild(bool createNewConsole); - SafeFileHandle GetStdOutputHandleForChild(bool createNewConsole); - SafeFileHandle GetStdErrorHandleForChild(bool createNewConsole); + SafeFileHandle? CreateStdInputHandleForChild(bool createNewConsole); + SafeFileHandle? CreateStdOutputHandleForChild(bool createNewConsole); + SafeFileHandle? CreateStdErrorHandleForChild(bool createNewConsole); bool HasConsoleWindow(); } @@ -28,9 +28,15 @@ private static IConsolePal CreatePlatformSpecificImpl() }; } - public static SafeFileHandle GetStdInputHandleForChild(bool createNewConsole) => Impl.GetStdInputHandleForChild(createNewConsole); - public static SafeFileHandle GetStdOutputHandleForChild(bool createNewConsole) => Impl.GetStdOutputHandleForChild(createNewConsole); - public static SafeFileHandle GetStdErrorHandleForChild(bool createNewConsole) => Impl.GetStdErrorHandleForChild(createNewConsole); + /// + /// Creates a duplicate handle to the stdin of the current process that can be inherited by a child process. + /// + /// + /// The created handle. if such an inheritable handle cannot be created. + /// + public static SafeFileHandle? CreateStdInputHandleForChild(bool createNewConsole) => Impl.CreateStdInputHandleForChild(createNewConsole); + public static SafeFileHandle? CreateStdOutputHandleForChild(bool createNewConsole) => Impl.CreateStdOutputHandleForChild(createNewConsole); + public static SafeFileHandle? CreateStdErrorHandleForChild(bool createNewConsole) => Impl.CreateStdErrorHandleForChild(createNewConsole); public static bool HasConsoleWindow() => Impl.HasConsoleWindow(); } } diff --git a/src/ChildProcess/PlatformAbstraction/Unix/UnixConsolePal.cs b/src/ChildProcess/PlatformAbstraction/Unix/UnixConsolePal.cs index ac2ca63..1952770 100644 --- a/src/ChildProcess/PlatformAbstraction/Unix/UnixConsolePal.cs +++ b/src/ChildProcess/PlatformAbstraction/Unix/UnixConsolePal.cs @@ -11,12 +11,12 @@ internal class UnixConsolePal : IConsolePal private const int StdOutFileNo = 1; private const int StdErrFileNo = 2; - public SafeFileHandle GetStdInputHandleForChild(bool createNewConsole) => - DuplicateStdFileForChild(StdInFileNo, createNewConsole) ?? FilePal.OpenNullDevice(System.IO.FileAccess.Read); - public SafeFileHandle GetStdOutputHandleForChild(bool createNewConsole) => - DuplicateStdFileForChild(StdOutFileNo, createNewConsole) ?? FilePal.OpenNullDevice(System.IO.FileAccess.Write); - public SafeFileHandle GetStdErrorHandleForChild(bool createNewConsole) => - DuplicateStdFileForChild(StdErrFileNo, createNewConsole) ?? FilePal.OpenNullDevice(System.IO.FileAccess.Write); + public SafeFileHandle? CreateStdInputHandleForChild(bool createNewConsole) => + DuplicateStdFileForChild(StdInFileNo, createNewConsole); + public SafeFileHandle? CreateStdOutputHandleForChild(bool createNewConsole) => + DuplicateStdFileForChild(StdOutFileNo, createNewConsole); + public SafeFileHandle? CreateStdErrorHandleForChild(bool createNewConsole) => + DuplicateStdFileForChild(StdErrFileNo, createNewConsole); private static SafeFileHandle? DuplicateStdFileForChild(int stdFd, bool createNewConsole) { diff --git a/src/ChildProcess/PlatformAbstraction/Windows/WindowsConsolePal.cs b/src/ChildProcess/PlatformAbstraction/Windows/WindowsConsolePal.cs index 4a537b2..a74b2e3 100644 --- a/src/ChildProcess/PlatformAbstraction/Windows/WindowsConsolePal.cs +++ b/src/ChildProcess/PlatformAbstraction/Windows/WindowsConsolePal.cs @@ -8,12 +8,12 @@ namespace Asmichi.PlatformAbstraction.Windows { internal sealed class WindowsConsolePal : IConsolePal { - public SafeFileHandle GetStdInputHandleForChild(bool createNewConsole) => - GetStdHandleForChild(Kernel32.STD_INPUT_HANDLE, createNewConsole) ?? FilePal.OpenNullDevice(System.IO.FileAccess.Read); - public SafeFileHandle GetStdOutputHandleForChild(bool createNewConsole) => - GetStdHandleForChild(Kernel32.STD_OUTPUT_HANDLE, createNewConsole) ?? FilePal.OpenNullDevice(System.IO.FileAccess.Write); - public SafeFileHandle GetStdErrorHandleForChild(bool createNewConsole) => - GetStdHandleForChild(Kernel32.STD_ERROR_HANDLE, createNewConsole) ?? FilePal.OpenNullDevice(System.IO.FileAccess.Write); + public SafeFileHandle? CreateStdInputHandleForChild(bool createNewConsole) => + GetStdHandleForChild(Kernel32.STD_INPUT_HANDLE, createNewConsole); + public SafeFileHandle? CreateStdOutputHandleForChild(bool createNewConsole) => + GetStdHandleForChild(Kernel32.STD_OUTPUT_HANDLE, createNewConsole); + public SafeFileHandle? CreateStdErrorHandleForChild(bool createNewConsole) => + GetStdHandleForChild(Kernel32.STD_ERROR_HANDLE, createNewConsole); /// /// Returns the std* handle of the current process that can be inherited by a child process. diff --git a/src/ChildProcess/ProcessManagement/PipelineStdHandleCreator.cs b/src/ChildProcess/ProcessManagement/PipelineStdHandleCreator.cs index 5b03337..6b4489d 100644 --- a/src/ChildProcess/ProcessManagement/PipelineStdHandleCreator.cs +++ b/src/ChildProcess/ProcessManagement/PipelineStdHandleCreator.cs @@ -193,7 +193,7 @@ private SafeHandle ChooseInput( { return redirection switch { - InputRedirection.ParentInput => ConsolePal.GetStdInputHandleForChild(createNewConsole), + InputRedirection.ParentInput => CreateStdInputHandleForChild(createNewConsole) ?? OpenNullDevice(FileAccess.Read), InputRedirection.InputPipe => inputPipe!, InputRedirection.File => OpenFile(fileName!, FileMode.Open, FileAccess.Read, FileShare.Read), InputRedirection.Handle => handle!, @@ -212,8 +212,8 @@ private SafeHandle ChooseOutput( { return redirection switch { - OutputRedirection.ParentOutput => ConsolePal.GetStdOutputHandleForChild(createNewConsole), - OutputRedirection.ParentError => ConsolePal.GetStdErrorHandleForChild(createNewConsole), + OutputRedirection.ParentOutput => CreateStdOutputHandleForChild(createNewConsole) ?? OpenNullDevice(FileAccess.Write), + OutputRedirection.ParentError => CreateStdErrorHandleForChild(createNewConsole) ?? OpenNullDevice(FileAccess.Write), OutputRedirection.OutputPipe => outputPipe!, OutputRedirection.ErrorPipe => errorPipe!, OutputRedirection.File => OpenFile(fileName!, FileMode.Create, FileAccess.Write, FileShare.Read), @@ -224,6 +224,39 @@ private SafeHandle ChooseOutput( }; } + private SafeFileHandle? CreateStdInputHandleForChild(bool createNewConsole) + { + var handle = ConsolePal.CreateStdInputHandleForChild(createNewConsole); + if (handle is null) + { + return null; + } + AddObjectsToDispose(handle); + return handle; + } + + private SafeFileHandle? CreateStdOutputHandleForChild(bool createNewConsole) + { + var handle = ConsolePal.CreateStdOutputHandleForChild(createNewConsole); + if (handle is null) + { + return null; + } + AddObjectsToDispose(handle); + return handle; + } + + private SafeFileHandle? CreateStdErrorHandleForChild(bool createNewConsole) + { + var handle = ConsolePal.CreateStdErrorHandleForChild(createNewConsole); + if (handle is null) + { + return null; + } + AddObjectsToDispose(handle); + return handle; + } + private SafeFileHandle OpenFile( string fileName, FileMode mode,