From 6ed1cb001416d6704a5af0f7d8c00ce3e5413d96 Mon Sep 17 00:00:00 2001 From: Mark Hammond Date: Thu, 29 Jan 2009 12:13:31 +0000 Subject: Fix issue5075: bdist_wininst should not depend on the vc runtime? --- Lib/distutils/command/wininst-9.0-amd64.exe | Bin 77824 -> 223744 bytes Lib/distutils/command/wininst-9.0.exe | Bin 66048 -> 196096 bytes PC/bdist_wininst/install.c | 179 ++++++++++++++-------------- PCbuild/bdist_wininst.vcproj | 4 +- 4 files changed, 92 insertions(+), 91 deletions(-) diff --git a/Lib/distutils/command/wininst-9.0-amd64.exe b/Lib/distutils/command/wininst-9.0-amd64.exe index 9dedfcd..11d8011 100644 Binary files a/Lib/distutils/command/wininst-9.0-amd64.exe and b/Lib/distutils/command/wininst-9.0-amd64.exe differ diff --git a/Lib/distutils/command/wininst-9.0.exe b/Lib/distutils/command/wininst-9.0.exe index 9102ecd..dadb31d 100644 Binary files a/Lib/distutils/command/wininst-9.0.exe and b/Lib/distutils/command/wininst-9.0.exe differ diff --git a/PC/bdist_wininst/install.c b/PC/bdist_wininst/install.c index 7e69eaa..ae8d0db 100644 --- a/PC/bdist_wininst/install.c +++ b/PC/bdist_wininst/install.c @@ -694,8 +694,9 @@ static int prepare_script_environment(HINSTANCE hPython) */ static int -run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv) +do_run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv) { + int fh, result; DECLPROC(hPython, void, Py_Initialize, (void)); DECLPROC(hPython, int, PySys_SetArgv, (int, char **)); DECLPROC(hPython, int, PyRun_SimpleString, (char *)); @@ -706,9 +707,6 @@ run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv) DECLPROC(hPython, int, PyArg_ParseTuple, (PyObject *, char *, ...)); DECLPROC(hPython, PyObject *, PyErr_Format, (PyObject *, char *)); - int result = 0; - int fh; - if (!Py_Initialize || !PySys_SetArgv || !PyRun_SimpleString || !Py_Finalize) return 1; @@ -730,7 +728,7 @@ run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv) } SetDlgItemText(hDialog, IDC_INFO, "Running Script..."); - + Py_Initialize(); prepare_script_environment(hPython); @@ -751,7 +749,57 @@ run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv) Py_Finalize(); close(fh); + return result; +} +static int +run_installscript(char *pathname, int argc, char **argv, char **pOutput) +{ + HINSTANCE hPython; + int result = 1; + int out_buf_size; + HANDLE redirected, old_stderr, old_stdout; + char *tempname; + + *pOutput = NULL; + + tempname = tempnam(NULL, NULL); + // We use a static CRT while the Python version we load uses + // the CRT from one of various possibile DLLs. As a result we + // need to redirect the standard handles using the API rather + // than the CRT. + redirected = CreateFile( + tempname, + GENERIC_WRITE | GENERIC_READ, + FILE_SHARE_READ, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, + NULL); + old_stdout = GetStdHandle(STD_OUTPUT_HANDLE); + old_stderr = GetStdHandle(STD_ERROR_HANDLE); + SetStdHandle(STD_OUTPUT_HANDLE, redirected); + SetStdHandle(STD_ERROR_HANDLE, redirected); + + hPython = LoadPythonDll(pythondll); + if (hPython) { + result = do_run_installscript(hPython, pathname, argc, argv); + FreeLibrary(hPython); + } else { + fprintf(stderr, "*** Could not load Python ***"); + } + SetStdHandle(STD_OUTPUT_HANDLE, old_stdout); + SetStdHandle(STD_ERROR_HANDLE, old_stderr); + out_buf_size = min(GetFileSize(redirected, NULL), 4096); + *pOutput = malloc(out_buf_size+1); + if (*pOutput) { + DWORD nread = 0; + SetFilePointer(redirected, 0, 0, FILE_BEGIN); + ReadFile(redirected, *pOutput, out_buf_size, &nread, NULL); + (*pOutput)[nread] = '\0'; + } + CloseHandle(redirected); + DeleteFile(tempname); return result; } @@ -781,11 +829,21 @@ static int do_run_simple_script(HINSTANCE hPython, char *script) static int run_simple_script(char *script) { int rc; - char *tempname; HINSTANCE hPython; - tempname = tempnam(NULL, NULL); - freopen(tempname, "a", stderr); - freopen(tempname, "a", stdout); + char *tempname = tempnam(NULL, NULL); + // Redirect output using win32 API - see comments above... + HANDLE redirected = CreateFile( + tempname, + GENERIC_WRITE | GENERIC_READ, + FILE_SHARE_READ, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, + NULL); + HANDLE old_stdout = GetStdHandle(STD_OUTPUT_HANDLE); + HANDLE old_stderr = GetStdHandle(STD_ERROR_HANDLE); + SetStdHandle(STD_OUTPUT_HANDLE, redirected); + SetStdHandle(STD_ERROR_HANDLE, redirected); hPython = LoadPythonDll(pythondll); if (!hPython) { @@ -796,10 +854,8 @@ static int run_simple_script(char *script) } rc = do_run_simple_script(hPython, script); FreeLibrary(hPython); - fflush(stderr); - fclose(stderr); - fflush(stdout); - fclose(stdout); + SetStdHandle(STD_OUTPUT_HANDLE, old_stdout); + SetStdHandle(STD_ERROR_HANDLE, old_stderr); /* We only care about the output when we fail. If the script works OK, then we discard it */ @@ -808,24 +864,24 @@ static int run_simple_script(char *script) char *err_buf; const char *prefix = "Running the pre-installation script failed\r\n"; int prefix_len = strlen(prefix); - FILE *fp = fopen(tempname, "rb"); - fseek(fp, 0, SEEK_END); - err_buf_size = ftell(fp); - fseek(fp, 0, SEEK_SET); + err_buf_size = GetFileSize(redirected, NULL); + if (err_buf_size==INVALID_FILE_SIZE) // an error - let's try anyway... + err_buf_size = 4096; err_buf = malloc(prefix_len + err_buf_size + 1); if (err_buf) { - int n; + DWORD n = 0; strcpy(err_buf, prefix); - n = fread(err_buf+prefix_len, 1, err_buf_size, fp); + SetFilePointer(redirected, 0, 0, FILE_BEGIN); + ReadFile(redirected, err_buf+prefix_len, err_buf_size, &n, NULL); err_buf[prefix_len+n] = '\0'; - fclose(fp); set_failure_reason(err_buf); free(err_buf); } else { set_failure_reason("Out of memory!"); } } - remove(tempname); + CloseHandle(redirected); + DeleteFile(tempname); return rc; } @@ -1946,12 +2002,9 @@ FinishedDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if (success && install_script && install_script[0]) { char fname[MAX_PATH]; - char *tempname; - FILE *fp; - char buffer[4096]; - int n; + char *buffer; HCURSOR hCursor; - HINSTANCE hPython; + int result; char *argv[3] = {NULL, "-install", NULL}; @@ -1964,48 +2017,21 @@ FinishedDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if (logfile) fprintf(logfile, "300 Run Script: [%s]%s\n", pythondll, fname); - tempname = tempnam(NULL, NULL); - - if (!freopen(tempname, "a", stderr)) - MessageBox(GetFocus(), "freopen stderr", NULL, MB_OK); - if (!freopen(tempname, "a", stdout)) - MessageBox(GetFocus(), "freopen stdout", NULL, MB_OK); -/* - if (0 != setvbuf(stdout, NULL, _IONBF, 0)) - MessageBox(GetFocus(), "setvbuf stdout", NULL, MB_OK); -*/ hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); argv[0] = fname; - hPython = LoadPythonDll(pythondll); - if (hPython) { - int result; - result = run_installscript(hPython, fname, 2, argv); - if (-1 == result) { - fprintf(stderr, "*** run_installscript: internal error 0x%X ***\n", result); - } - FreeLibrary(hPython); - } else { - fprintf(stderr, "*** Could not load Python ***"); + result = run_installscript(fname, 2, argv, &buffer); + if (0 != result) { + fprintf(stderr, "*** run_installscript: internal error 0x%X ***\n", result); } - fflush(stderr); - fclose(stderr); - fflush(stdout); - fclose(stdout); - - fp = fopen(tempname, "rb"); - n = fread(buffer, 1, sizeof(buffer), fp); - fclose(fp); - remove(tempname); - - buffer[n] = '\0'; - - SetDlgItemText(hwnd, IDC_INFO, buffer); + if (buffer) + SetDlgItemText(hwnd, IDC_INFO, buffer); SetDlgItemText(hwnd, IDC_TITLE, "Postinstall script finished.\n" "Click the Finish button to exit the Setup wizard."); + free(buffer); SetCursor(hCursor); CloseLogfile(); } @@ -2418,42 +2444,17 @@ BOOL Run_RemoveScript(char *line) /* this function may be called more than one time with the same script, only run it one time */ if (strcmp(lastscript, scriptname)) { - HINSTANCE hPython; char *argv[3] = {NULL, "-remove", NULL}; - char buffer[4096]; - FILE *fp; - char *tempname; - int n; + char *buffer = NULL; argv[0] = scriptname; - tempname = tempnam(NULL, NULL); + if (0 != run_installscript(scriptname, 2, argv, &buffer)) + fprintf(stderr, "*** Could not run installation script ***"); - if (!freopen(tempname, "a", stderr)) - MessageBox(GetFocus(), "freopen stderr", NULL, MB_OK); - if (!freopen(tempname, "a", stdout)) - MessageBox(GetFocus(), "freopen stdout", NULL, MB_OK); - - hPython = LoadLibrary(dllname); - if (hPython) { - if (0x80000000 == run_installscript(hPython, scriptname, 2, argv)) - fprintf(stderr, "*** Could not load Python ***"); - FreeLibrary(hPython); - } - - fflush(stderr); - fclose(stderr); - fflush(stdout); - fclose(stdout); - - fp = fopen(tempname, "rb"); - n = fread(buffer, 1, sizeof(buffer), fp); - fclose(fp); - remove(tempname); - - buffer[n] = '\0'; - if (buffer[0]) + if (buffer && buffer[0]) MessageBox(GetFocus(), buffer, "uninstall-script", MB_OK); + free(buffer); strcpy(lastscript, scriptname); } diff --git a/PCbuild/bdist_wininst.vcproj b/PCbuild/bdist_wininst.vcproj index fd877c4..f15755f 100644 --- a/PCbuild/bdist_wininst.vcproj +++ b/PCbuild/bdist_wininst.vcproj @@ -55,7 +55,7 @@ AdditionalIncludeDirectories="..\PC\bdist_wininst;..\Include;..\Modules\zlib" PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE" StringPooling="true" - RuntimeLibrary="2" + RuntimeLibrary="0" EnableFunctionLevelLinking="true" WarningLevel="3" SuppressStartupBanner="true" @@ -145,7 +145,7 @@ AdditionalIncludeDirectories="..\PC\bdist_wininst;..\Include;..\Modules\zlib" PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE" StringPooling="true" - RuntimeLibrary="2" + RuntimeLibrary="0" EnableFunctionLevelLinking="true" WarningLevel="3" SuppressStartupBanner="true" -- cgit v0.12