Skip to content
Snippets Groups Projects
Commit 3ec579d5 authored by Tamar Christina's avatar Tamar Christina
Browse files

Release console for ghci wrapper

Summary:
It seems the call that caused issues with the gcc wrapper before
was needed for the ghci wrapper in order for the child process
to be the one handling console events.

This code slightly refactors the wrappers to make sure only ghci
calls FreeConsole and nothing else.

Test Plan: ./validate , open ghci.exe press ctrl+c

Reviewers: RyanGlScott, austin, hvr, bgamari

Reviewed By: bgamari

Subscribers: rwbarton, thomie, erikd

GHC Trac Issues: #14150

Differential Revision: https://phabricator.haskell.org/D4028
parent f9f1e38c
No related branches found
No related tags found
No related merge requests found
......@@ -61,6 +61,6 @@ int main(int argc, char** argv) {
preArgv[2] = mkString("-B%s/../lib/gcc/%s/%s" , binDir, base, version);
preArgv[3] = mkString("-B%s/../libexec/gcc/%s/%s", binDir, base, version);
run(exePath, 4, preArgv, argc - 1, argv + 1);
run(exePath, 4, preArgv, argc - 1, argv + 1, NULL);
}
......@@ -10,5 +10,5 @@ int main(int argc, char** argv) {
binDir = getExecutablePath();
exePath = mkString("%s/ghc.exe", binDir);
run(exePath, 0, NULL, argc - 1, argv + 1);
run(exePath, 0, NULL, argc - 1, argv + 1, NULL);
}
......@@ -11,6 +11,16 @@ BOOL fileExists(const char *path) {
return r != INVALID_FILE_ATTRIBUTES && !(r & FILE_ATTRIBUTE_DIRECTORY);
}
/* In order for this console program to pass on full event processing to called
process we need to remove it from the current console. Since we want the
child to inherit the handles so redirection etc all work we need to detach
from the console after the child has been created. However we don't want to
detach from the console in non-interactive scenarios otherwise we'll hit
#13411 again. So we only detach when we're sure we need to, see #14150. */
void ReleaseResource(void) {
FreeConsole();
}
int main(int argc, char** argv) {
char *binDir;
char *exePath;
......@@ -33,6 +43,5 @@ int main(int argc, char** argv) {
exePath = mkString("%s/ghc-stage2.exe", binDir);
}
run(exePath, 1, preArgv, argc - 1, argv + 1);
run(exePath, 1, preArgv, argc - 1, argv + 1, ReleaseResource);
}
......@@ -10,5 +10,5 @@ int main(int argc, char** argv) {
binDir = getExecutablePath();
exePath = mkString("%s/haddock.exe", binDir);
run(exePath, 0, NULL, argc - 1, argv + 1);
run(exePath, 0, NULL, argc - 1, argv + 1, NULL);
}
......@@ -70,9 +70,12 @@ char *flattenAndQuoteArgs(char *ptr, int argc, char *argv[])
return ptr;
}
/* This function takes a callback to be called after the creation of the child
process but before we block waiting for the child. Can be NULL. */
__attribute__((noreturn)) int run (char *exePath,
int numArgs1, char **args1,
int numArgs2, char **args2)
int numArgs2, char **args2,
runCallback callback)
{
int i, cmdline_len;
char *new_cmdline, *ptr;
......@@ -134,6 +137,10 @@ __attribute__((noreturn)) int run (char *exePath,
/* Synchronize input and wait for target to be ready. */
WaitForInputIdle(pi.hProcess, INFINITE);
/* If we have a registered callback then call it before we block. */
if (callback)
callback();
switch (WaitForSingleObject(pi.hProcess, INFINITE) ) {
case WAIT_OBJECT_0:
{
......
void die(const char *fmt, ...);
char *mkString(const char *fmt, ...);
__attribute__((noreturn)) int run(char *exePath, int numArgs1, char **args1, int numArgs2, char **args2);
typedef void (*runCallback)(void);
__attribute__((noreturn)) int run(char *exePath, int numArgs1, char **args1,
int numArgs2, char **args2,
runCallback callback);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment