[Ada] Fix exit status of GNAT.Expect.Close call on running process

Message ID 20220107162710.GA948487@adacore.com
State Committed
Commit 9e6274e0a3b60e77a42784c3fb6ef2aa3cfc071a
Headers
Series [Ada] Fix exit status of GNAT.Expect.Close call on running process |

Commit Message

Pierre-Marie de Rodat Jan. 7, 2022, 4:27 p.m. UTC
  Fix exit status processing logic in __gnat_waitpid.  Fix
GNAT.Expect.Interrupt on Windows.  It was terminating the calling
process.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

	* expect.c (__gnat_waitpid): Use macros WIFEXITED, WEXITSTATUS,
	WIFSIGNALED, WTERMSIG, WIFSTOPPED, WSTOPSIG to get exit status
	or signal that caused the child process to terminate/stop.  Do
	not process exit status in case of error in waitpid call.
	* adaint.c (__gnat_kill): Use of GenerateConsoleCtrlEvent is
	removed in Windows variant as it actually is not working and was
	terminating the calling process.  Set signal number into exit
	code parameter of TerminateProcess to work the same like in
	Linux.
  

Patch

diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -3562,18 +3562,8 @@  __gnat_kill (int pid, int sig, int close ATTRIBUTE_UNUSED)
   HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
   if (h == NULL)
     return;
-  if (sig == 9)
-    {
-      TerminateProcess (h, 1);
-    }
-  else if (sig == SIGINT)
-    GenerateConsoleCtrlEvent (CTRL_C_EVENT, pid);
-  else if (sig == SIGBREAK)
-    GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid);
-  /* ??? The last two alternatives don't really work. SIGBREAK requires setting
-     up process groups at start time which we don't do; treating SIGINT is just
-     not possible apparently. So we really only support signal 9. Fortunately
-     that's all we use in GNAT.Expect */
+
+  TerminateProcess (h, sig);
 
   CloseHandle (h);
 #elif defined (__vxworks)


diff --git a/gcc/ada/expect.c b/gcc/ada/expect.c
--- a/gcc/ada/expect.c
+++ b/gcc/ada/expect.c
@@ -345,8 +345,17 @@  __gnat_waitpid (int pid)
 {
   int status = 0;
 
-  waitpid (pid, &status, 0);
-  status = WEXITSTATUS (status);
+  if (waitpid (pid, &status, 0) == -1) {
+     return -1;
+  }
+
+  if WIFEXITED (status) {
+     status = WEXITSTATUS (status);
+  } else if WIFSIGNALED (status) {
+     status = WTERMSIG (status);
+  } else if WIFSTOPPED (status) {
+     status = WSTOPSIG (status);
+  }
 
   return status;
 }