diff options
author | Nicolas Roche <roche@adacore.com> | 2019-07-22 13:56:45 +0000 |
---|---|---|
committer | Pierre-Marie de Rodat <pmderodat@gcc.gnu.org> | 2019-07-22 13:56:45 +0000 |
commit | 1a79e03b8012d5094e5bd432df59abeca5c2fe18 (patch) | |
tree | 48f88a355759883e437a94913f8890a9695587ed /gcc/ada/terminals.c | |
parent | 4123b473427ca6854f874c77f5ce78c7e8c133a7 (diff) | |
download | gcc-1a79e03b8012d5094e5bd432df59abeca5c2fe18.zip gcc-1a79e03b8012d5094e5bd432df59abeca5c2fe18.tar.gz gcc-1a79e03b8012d5094e5bd432df59abeca5c2fe18.tar.bz2 |
[Ada] Ensure Ctrl-C is not emited on terminated processes
Due to the reuse policy of PID on Windows. Sending a Ctrl-C to a dead
process might result in a Ctrl-C sent to the wrong process. The check is
also implemented on Unix platforms and avoid unecessary waits.
2019-07-22 Nicolas Roche <roche@adacore.com>
gcc/ada/
* terminals.c (__gnat_tty_waitpid): Support both blocking and
not blocking mode.
* libgnat/g-exptty.ads (Is_Process_Running): New function.
* libgnat/g-exptty.adb (Close): Don't try to interrupt/terminate
a process if it is already dead.
From-SVN: r273672
Diffstat (limited to 'gcc/ada/terminals.c')
-rw-r--r-- | gcc/ada/terminals.c | 45 |
1 files changed, 32 insertions, 13 deletions
diff --git a/gcc/ada/terminals.c b/gcc/ada/terminals.c index 23f9dfd..320ad28 100644 --- a/gcc/ada/terminals.c +++ b/gcc/ada/terminals.c @@ -108,7 +108,7 @@ __gnat_tty_supported (void) } int -__gnat_tty_waitpid (void *desc ATTRIBUTE_UNUSED) +__gnat_tty_waitpid (void *desc ATTRIBUTE_UNUSED, int blocking) { return 1; } @@ -152,6 +152,7 @@ __gnat_setup_winsize (void *desc ATTRIBUTE_UNUSED, #include <stdlib.h> #include <windows.h> +#include <winternl.h> #define MAXPATHLEN 1024 @@ -1014,20 +1015,28 @@ __gnat_terminate_pid (int pid) the Win32 API instead of the C one. */ int -__gnat_tty_waitpid (struct TTY_Process* p) +__gnat_tty_waitpid (struct TTY_Process* p, int blocking) { DWORD exitcode; - DWORD res; - HANDLE proc_hand = p->procinfo.hProcess; + HANDLE hprocess = p->procinfo.hProcess; - res = WaitForSingleObject (proc_hand, 0); - GetExitCodeProcess (proc_hand, &exitcode); + if (blocking) { + /* Wait is needed on Windows only in blocking mode. */ + WaitForSingleObject (hprocess, 0); + } - CloseHandle (p->procinfo.hThread); - CloseHandle (p->procinfo.hProcess); + GetExitCodeProcess (hprocess, &exitcode); - /* No need to close the handles: they were closed on the ada side */ + if (exitcode == STILL_ACTIVE) { + /* If process is still active return -1. */ + exitcode = -1; + } else { + /* Process is dead, so handle to process and main thread can be closed. */ + CloseHandle (p->procinfo.hThread); + CloseHandle (hprocess); + } + /* No need to close the handles: they were closed on the ada side */ return (int) exitcode; } @@ -1556,11 +1565,21 @@ __gnat_terminate_pid (int pid) * exit status of the child process */ int -__gnat_tty_waitpid (pty_desc *desc) +__gnat_tty_waitpid (pty_desc *desc, int blocking) { - int status = 0; - waitpid (desc->child_pid, &status, 0); - return WEXITSTATUS (status); + int status = -1; + int options = 0; + + if (blocking) { + options = 0; + } else { + options = WNOHANG; + } + waitpid (desc->child_pid, &status, options); + if WIFEXITED (status) { + status = WEXITSTATUS (status); + } + return status; } /* __gnat_tty_supported - Are tty supported ? |