Преглед на файлове

BfpProcess_WaitFor, BeefCon shutdown fix

Brian Fiete преди 9 месеца
родител
ревизия
c8dda5d1d9

+ 6 - 1
BeefLibs/corlib/src/Platform.bf

@@ -211,7 +211,9 @@ namespace System
 		public enum BfpProcessResult : int32
 		{
 			Ok = (int)Result.Ok,
-			InsufficientBuffer = (int)Result.InsufficientBuffer
+			NotFound = (int)Result.NotFound,
+			InsufficientBuffer = (int)Result.InsufficientBuffer,
+			UnknownError = (int)Result.UnknownError,
 		}
 
 #if !BF_RUNTIME_DISABLE
@@ -229,6 +231,9 @@ namespace System
 		public static extern void BfpProcess_GetProcessName(BfpProcess* process, char8* outName, int32* inOutNameSize, BfpProcessResult* outResult);
 		[CallingConvention(.Stdcall), CLink]
 		public static extern int32 BfpProcess_GetProcessId(BfpProcess* process);
+		[CallingConvention(.Stdcall), CLink]
+		public static extern bool BfpProcess_WaitFor(BfpProcess* process, int waitMS, int* outExitCode, BfpProcessResult* outResult);
+
 #else
 		
 		public static bool BfpProcess_IsRemoteMachine(char8* machineName) => Runtime.NotImplemented();

+ 31 - 2
BeefTools/BeefCon/src/Program.bf

@@ -19,6 +19,17 @@ class Program
 	String mExecStr = new .() ~ delete _;
 	SpawnedProcess mSpawnedProcess ~ delete _;
 
+	[CLink, CallingConvention(.Stdcall)]
+	public static extern Windows.IntBool AttachConsole(int processId);
+
+	[CallingConvention(.Stdcall)]
+	function Windows.IntBool ConsoleCtrlHandler(int32 ctrlType);
+	[CLink, CallingConvention(.Stdcall)]
+	static extern Windows.IntBool SetConsoleCtrlHandler(ConsoleCtrlHandler handler, Windows.IntBool addHandler);
+
+	[CLink, CallingConvention(.Stdcall)]
+	static extern Windows.IntBool GenerateConsoleCtrlEvent(uint32 dwCtrlEvent, uint32 dwProcessGroupId);
+
 	public ~this()
 	{
 		if (mSpawnedProcess != null)
@@ -165,13 +176,21 @@ class Program
 			// Check BeefIDE process
 			if ((mPid != 123) || (!Debug.IsDebuggerPresent))
 			{
+				bool isProcessOpen = false;
+
 				var process = Platform.BfpProcess_GetById(null, mPid, null);
-				if (process == null)
+				if (process != null)
+				{
+					if (!Platform.BfpProcess_WaitFor(process, 0, null, null))
+						isProcessOpen = true;
+					Platform.BfpProcess_Release(process);
+				}
+
+				if (!isProcessOpen)
 				{
 					Console.Error.WriteLine("Process closed");
 					return;
 				}
-				Platform.BfpProcess_Release(process);
 			}
 
 			MessageLoop();
@@ -267,6 +286,16 @@ class Program
 			pg.mExecStr.Set(args[2]);
 			pg.Run();
 		}
+		else if (args.Count >= 2)
+		{
+			pg.mPid = int32.Parse(args[0]);
+			if (args[1] == "kill")
+			{
+				AttachConsole(pg.mPid);
+				SetConsoleCtrlHandler(default, true);
+				GenerateConsoleCtrlEvent(/*CTRL_C_EVENT*/0, 0);
+			}
+		}
 		else
 		{
 			pg.mPid = int32.Parse(args[0]);

+ 1 - 0
BeefySysLib/platform/PlatformInterface.h

@@ -180,6 +180,7 @@ BFP_EXPORT bool BFP_CALLTYPE BfpProcess_IsRemoteMachine(const char* machineName)
 BFP_EXPORT BfpProcess* BFP_CALLTYPE BfpProcess_GetById(const char* machineName, int processId, BfpProcessResult* outResult);
 BFP_EXPORT void BFP_CALLTYPE BfpProcess_Enumerate(const char* machineName, BfpProcess** outProcesses, int* inOutProcessesSize, BfpProcessResult* outResult);
 BFP_EXPORT void BFP_CALLTYPE BfpProcess_Release(BfpProcess* process);
+BFP_EXPORT int BFP_CALLTYPE BfpProcess_GetExitCode(BfpProcess* process, BfpProcessResult* outResult);
 BFP_EXPORT void BFP_CALLTYPE BfpProcess_GetMainWindowTitle(BfpProcess* process, char* outTitle, int* inOutTitleSize, BfpProcessResult* outResult);
 BFP_EXPORT void BFP_CALLTYPE BfpProcess_GetProcessName(BfpProcess* process, char* outName, int* inOutNameSize, BfpProcessResult* outResult);
 BFP_EXPORT int BFP_CALLTYPE BfpProcess_GetProcessId(BfpProcess* process);

+ 5 - 0
BeefySysLib/platform/posix/PosixCommon.cpp

@@ -858,6 +858,11 @@ BFP_EXPORT void BFP_CALLTYPE BfpProcess_Release(BfpProcess* process)
     NOT_IMPL;
 }
 
+BFP_EXPORT bool BFP_CALLTYPE BfpProcess_WaitFor(BfpProcess* process, int waitMS, int* outExitCode, BfpProcessResult* outResult)
+{
+    NOT_IMPL;
+}
+
 BFP_EXPORT void BFP_CALLTYPE BfpProcess_GetMainWindowTitle(BfpProcess* process, char* outTitle, int* inOutTitleSize, BfpProcessResult* outResult)
 {
     NOT_IMPL;

+ 36 - 3
BeefySysLib/platform/win/Platform.cpp

@@ -1285,7 +1285,15 @@ struct BfpProcess
 {
 	int mProcessId;
 	SYSTEM_PROCESS_INFORMATION* mInfo;
+	HANDLE mProcess;
 	String mImageName;
+
+	BfpProcess()
+	{
+		mProcessId = -1;
+		mInfo = NULL;
+		mProcess = 0;
+	}
 };
 
 BFP_EXPORT bool BFP_CALLTYPE BfpProcess_IsRemoteMachine(const char* machineName)
@@ -1295,16 +1303,16 @@ BFP_EXPORT bool BFP_CALLTYPE BfpProcess_IsRemoteMachine(const char* machineName)
 
 BFP_EXPORT BfpProcess* BFP_CALLTYPE BfpProcess_GetById(const char* machineName, int processId, BfpProcessResult* outResult)
 {
-	HANDLE hProc = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processId);
+	HANDLE hProc = ::OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, processId);
 	if (hProc == NULL)
 	{
 		OUTRESULT(BfpProcessResult_NotFound);
 		return NULL;
-	}	
-	::CloseHandle(hProc);
+	}		
 
 	BfpProcess* process = new BfpProcess();
 	process->mProcessId = processId;
+	process->mProcess = hProc;
 	process->mInfo = NULL;
 	return process;
 }
@@ -1395,9 +1403,34 @@ BFP_EXPORT void BFP_CALLTYPE BfpProcess_Release(BfpProcess* process)
 {
 	if (process->mInfo != NULL)
 		free(process->mInfo);
+	if (process->mProcess != NULL)
+		::CloseHandle(process->mProcess);
 	delete process;
 }
 
+BFP_EXPORT bool BFP_CALLTYPE BfpProcess_WaitFor(BfpProcess* process, int waitMS, int* outExitCode, BfpProcessResult* outResult)
+{
+	if (process->mProcess == NULL)	
+	{
+		OUTRESULT(BfpProcessResult_NotFound);
+		return false;
+	}
+
+	if (::WaitForSingleObject(process->mProcess, waitMS) != WAIT_OBJECT_0)
+	{
+		OUTRESULT(BfpProcessResult_NotFound);
+		return false;
+	}
+
+	DWORD errorCode = 0;
+	GetExitCodeProcess(process->mProcess, &errorCode);
+	if (outExitCode != NULL)
+		*outExitCode = (int)errorCode;
+
+	OUTRESULT(BfpProcessResult_Ok);
+	return true;
+}
+
 //struct EnumWndData
 //{
 //	HWND mBestHandle;