summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamar Christina <tamar@zhox.com>2019-06-01 11:10:56 +0100
committerAndreas Klebinger <klebinger.andreas@gmx.at>2020-05-19 18:59:39 +0200
commit42df3415af188c17ecbad4cdc6183dd8c5125dae (patch)
tree948a8b72202c6b8fe9c62175e7404878cbb80503
parent568d7279a80cf945271f0659f11a94eea3f1433d (diff)
downloadhaskell-wip/andreask/wio/gcc_driver.tar.gz
winio: Isolate GCC driver a bit more from external incompatible shared libs, (e.g. pthreads from another installation.)wip/andreask/wio/gcc_driver
-rw-r--r--driver/gcc/gcc.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/driver/gcc/gcc.c b/driver/gcc/gcc.c
index aa63bb0498..16238667b2 100644
--- a/driver/gcc/gcc.c
+++ b/driver/gcc/gcc.c
@@ -10,6 +10,10 @@
#include <stdio.h>
#include <stdlib.h>
+#include <windows.h>
+
+typedef DLL_DIRECTORY_COOKIE(WINAPI *LPAddDLLDirectory)(PCWSTR NewDirectory);
+typedef WINBOOL(WINAPI *LPRemoveDLLDirectory)(DLL_DIRECTORY_COOKIE Cookie);
int main(int argc, char** argv) {
char *binDir;
@@ -32,14 +36,14 @@ int main(int argc, char** argv) {
if (!oldPath) {
die("Couldn't read PATH\n");
}
- n = snprintf(NULL, 0, "PATH=%s;%s", binDir, oldPath);
+ n = snprintf(NULL, 0, "%s;%s", binDir, oldPath);
n++;
newPath = malloc(n);
if (!newPath) {
die("Couldn't allocate space for PATH\n");
}
- snprintf(newPath, n, "PATH=%s;%s", binDir, oldPath);
- n = putenv(newPath);
+ snprintf(newPath, n, "%s;%s", binDir, oldPath);
+ n = _putenv_s("PATH", newPath);
if (n) {
die("putenv failed\n");
}
@@ -61,6 +65,27 @@ 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);
+ HINSTANCE hDLL = LoadLibraryW(L"Kernel32.DLL");
+ LPAddDLLDirectory AddDllDirectory
+ = (LPAddDLLDirectory)GetProcAddress((HMODULE)hDLL, "AddDllDirectory");
+ LPRemoveDLLDirectory RemoveDllDirectory
+ = (LPRemoveDLLDirectory)GetProcAddress((HMODULE)hDLL, "RemoveDllDirectory");
+ DLL_DIRECTORY_COOKIE cookie;
+
+ if (AddDllDirectory && RemoveDllDirectory)
+ {
+ size_t size = strlen(binDir) + 1;
+ wchar_t* s_binDir = calloc (size, sizeof (wchar_t));
+
+ size_t outSize;
+ mbstowcs_s(&outSize, s_binDir, size, binDir, size - 1);
+
+ cookie = AddDllDirectory (s_binDir);
+ }
+
run(exePath, 4, preArgv, argc - 1, argv + 1, NULL);
+
+ if (AddDllDirectory && RemoveDllDirectory)
+ RemoveDllDirectory (cookie);
}