Skip to content

Commit 189cfab

Browse files
author
mark.hammond
committed
Fix issue5075: bdist_wininst should not depend on the vc runtime?
git-svn-id: http://svn.python.org/projects/python/trunk@69094 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 7ff3249 commit 189cfab

File tree

4 files changed

+92
-91
lines changed

4 files changed

+92
-91
lines changed
143 KB
Binary file not shown.
127 KB
Binary file not shown.

PC/bdist_wininst/install.c

Lines changed: 90 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -694,8 +694,9 @@ static int prepare_script_environment(HINSTANCE hPython)
694694
*/
695695

696696
static int
697-
run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv)
697+
do_run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv)
698698
{
699+
int fh, result;
699700
DECLPROC(hPython, void, Py_Initialize, (void));
700701
DECLPROC(hPython, int, PySys_SetArgv, (int, char **));
701702
DECLPROC(hPython, int, PyRun_SimpleString, (char *));
@@ -706,9 +707,6 @@ run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv)
706707
DECLPROC(hPython, int, PyArg_ParseTuple, (PyObject *, char *, ...));
707708
DECLPROC(hPython, PyObject *, PyErr_Format, (PyObject *, char *));
708709

709-
int result = 0;
710-
int fh;
711-
712710
if (!Py_Initialize || !PySys_SetArgv
713711
|| !PyRun_SimpleString || !Py_Finalize)
714712
return 1;
@@ -730,7 +728,7 @@ run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv)
730728
}
731729

732730
SetDlgItemText(hDialog, IDC_INFO, "Running Script...");
733-
731+
734732
Py_Initialize();
735733

736734
prepare_script_environment(hPython);
@@ -751,7 +749,57 @@ run_installscript(HINSTANCE hPython, char *pathname, int argc, char **argv)
751749
Py_Finalize();
752750

753751
close(fh);
752+
return result;
753+
}
754754

755+
static int
756+
run_installscript(char *pathname, int argc, char **argv, char **pOutput)
757+
{
758+
HINSTANCE hPython;
759+
int result = 1;
760+
int out_buf_size;
761+
HANDLE redirected, old_stderr, old_stdout;
762+
char *tempname;
763+
764+
*pOutput = NULL;
765+
766+
tempname = tempnam(NULL, NULL);
767+
// We use a static CRT while the Python version we load uses
768+
// the CRT from one of various possibile DLLs. As a result we
769+
// need to redirect the standard handles using the API rather
770+
// than the CRT.
771+
redirected = CreateFile(
772+
tempname,
773+
GENERIC_WRITE | GENERIC_READ,
774+
FILE_SHARE_READ,
775+
NULL,
776+
CREATE_ALWAYS,
777+
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
778+
NULL);
779+
old_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
780+
old_stderr = GetStdHandle(STD_ERROR_HANDLE);
781+
SetStdHandle(STD_OUTPUT_HANDLE, redirected);
782+
SetStdHandle(STD_ERROR_HANDLE, redirected);
783+
784+
hPython = LoadPythonDll(pythondll);
785+
if (hPython) {
786+
result = do_run_installscript(hPython, pathname, argc, argv);
787+
FreeLibrary(hPython);
788+
} else {
789+
fprintf(stderr, "*** Could not load Python ***");
790+
}
791+
SetStdHandle(STD_OUTPUT_HANDLE, old_stdout);
792+
SetStdHandle(STD_ERROR_HANDLE, old_stderr);
793+
out_buf_size = min(GetFileSize(redirected, NULL), 4096);
794+
*pOutput = malloc(out_buf_size+1);
795+
if (*pOutput) {
796+
DWORD nread = 0;
797+
SetFilePointer(redirected, 0, 0, FILE_BEGIN);
798+
ReadFile(redirected, *pOutput, out_buf_size, &nread, NULL);
799+
(*pOutput)[nread] = '\0';
800+
}
801+
CloseHandle(redirected);
802+
DeleteFile(tempname);
755803
return result;
756804
}
757805

@@ -781,11 +829,21 @@ static int do_run_simple_script(HINSTANCE hPython, char *script)
781829
static int run_simple_script(char *script)
782830
{
783831
int rc;
784-
char *tempname;
785832
HINSTANCE hPython;
786-
tempname = tempnam(NULL, NULL);
787-
freopen(tempname, "a", stderr);
788-
freopen(tempname, "a", stdout);
833+
char *tempname = tempnam(NULL, NULL);
834+
// Redirect output using win32 API - see comments above...
835+
HANDLE redirected = CreateFile(
836+
tempname,
837+
GENERIC_WRITE | GENERIC_READ,
838+
FILE_SHARE_READ,
839+
NULL,
840+
CREATE_ALWAYS,
841+
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
842+
NULL);
843+
HANDLE old_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
844+
HANDLE old_stderr = GetStdHandle(STD_ERROR_HANDLE);
845+
SetStdHandle(STD_OUTPUT_HANDLE, redirected);
846+
SetStdHandle(STD_ERROR_HANDLE, redirected);
789847

790848
hPython = LoadPythonDll(pythondll);
791849
if (!hPython) {
@@ -796,10 +854,8 @@ static int run_simple_script(char *script)
796854
}
797855
rc = do_run_simple_script(hPython, script);
798856
FreeLibrary(hPython);
799-
fflush(stderr);
800-
fclose(stderr);
801-
fflush(stdout);
802-
fclose(stdout);
857+
SetStdHandle(STD_OUTPUT_HANDLE, old_stdout);
858+
SetStdHandle(STD_ERROR_HANDLE, old_stderr);
803859
/* We only care about the output when we fail. If the script works
804860
OK, then we discard it
805861
*/
@@ -808,24 +864,24 @@ static int run_simple_script(char *script)
808864
char *err_buf;
809865
const char *prefix = "Running the pre-installation script failed\r\n";
810866
int prefix_len = strlen(prefix);
811-
FILE *fp = fopen(tempname, "rb");
812-
fseek(fp, 0, SEEK_END);
813-
err_buf_size = ftell(fp);
814-
fseek(fp, 0, SEEK_SET);
867+
err_buf_size = GetFileSize(redirected, NULL);
868+
if (err_buf_size==INVALID_FILE_SIZE) // an error - let's try anyway...
869+
err_buf_size = 4096;
815870
err_buf = malloc(prefix_len + err_buf_size + 1);
816871
if (err_buf) {
817-
int n;
872+
DWORD n = 0;
818873
strcpy(err_buf, prefix);
819-
n = fread(err_buf+prefix_len, 1, err_buf_size, fp);
874+
SetFilePointer(redirected, 0, 0, FILE_BEGIN);
875+
ReadFile(redirected, err_buf+prefix_len, err_buf_size, &n, NULL);
820876
err_buf[prefix_len+n] = '\0';
821-
fclose(fp);
822877
set_failure_reason(err_buf);
823878
free(err_buf);
824879
} else {
825880
set_failure_reason("Out of memory!");
826881
}
827882
}
828-
remove(tempname);
883+
CloseHandle(redirected);
884+
DeleteFile(tempname);
829885
return rc;
830886
}
831887

@@ -1946,12 +2002,9 @@ FinishedDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
19462002

19472003
if (success && install_script && install_script[0]) {
19482004
char fname[MAX_PATH];
1949-
char *tempname;
1950-
FILE *fp;
1951-
char buffer[4096];
1952-
int n;
2005+
char *buffer;
19532006
HCURSOR hCursor;
1954-
HINSTANCE hPython;
2007+
int result;
19552008

19562009
char *argv[3] = {NULL, "-install", NULL};
19572010

@@ -1964,48 +2017,21 @@ FinishedDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
19642017
if (logfile)
19652018
fprintf(logfile, "300 Run Script: [%s]%s\n", pythondll, fname);
19662019

1967-
tempname = tempnam(NULL, NULL);
1968-
1969-
if (!freopen(tempname, "a", stderr))
1970-
MessageBox(GetFocus(), "freopen stderr", NULL, MB_OK);
1971-
if (!freopen(tempname, "a", stdout))
1972-
MessageBox(GetFocus(), "freopen stdout", NULL, MB_OK);
1973-
/*
1974-
if (0 != setvbuf(stdout, NULL, _IONBF, 0))
1975-
MessageBox(GetFocus(), "setvbuf stdout", NULL, MB_OK);
1976-
*/
19772020
hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
19782021

19792022
argv[0] = fname;
19802023

1981-
hPython = LoadPythonDll(pythondll);
1982-
if (hPython) {
1983-
int result;
1984-
result = run_installscript(hPython, fname, 2, argv);
1985-
if (-1 == result) {
1986-
fprintf(stderr, "*** run_installscript: internal error 0x%X ***\n", result);
1987-
}
1988-
FreeLibrary(hPython);
1989-
} else {
1990-
fprintf(stderr, "*** Could not load Python ***");
2024+
result = run_installscript(fname, 2, argv, &buffer);
2025+
if (0 != result) {
2026+
fprintf(stderr, "*** run_installscript: internal error 0x%X ***\n", result);
19912027
}
1992-
fflush(stderr);
1993-
fclose(stderr);
1994-
fflush(stdout);
1995-
fclose(stdout);
1996-
1997-
fp = fopen(tempname, "rb");
1998-
n = fread(buffer, 1, sizeof(buffer), fp);
1999-
fclose(fp);
2000-
remove(tempname);
2001-
2002-
buffer[n] = '\0';
2003-
2004-
SetDlgItemText(hwnd, IDC_INFO, buffer);
2028+
if (buffer)
2029+
SetDlgItemText(hwnd, IDC_INFO, buffer);
20052030
SetDlgItemText(hwnd, IDC_TITLE,
20062031
"Postinstall script finished.\n"
20072032
"Click the Finish button to exit the Setup wizard.");
20082033

2034+
free(buffer);
20092035
SetCursor(hCursor);
20102036
CloseLogfile();
20112037
}
@@ -2418,42 +2444,17 @@ BOOL Run_RemoveScript(char *line)
24182444
/* this function may be called more than one time with the same
24192445
script, only run it one time */
24202446
if (strcmp(lastscript, scriptname)) {
2421-
HINSTANCE hPython;
24222447
char *argv[3] = {NULL, "-remove", NULL};
2423-
char buffer[4096];
2424-
FILE *fp;
2425-
char *tempname;
2426-
int n;
2448+
char *buffer = NULL;
24272449

24282450
argv[0] = scriptname;
24292451

2430-
tempname = tempnam(NULL, NULL);
2452+
if (0 != run_installscript(scriptname, 2, argv, &buffer))
2453+
fprintf(stderr, "*** Could not run installation script ***");
24312454

2432-
if (!freopen(tempname, "a", stderr))
2433-
MessageBox(GetFocus(), "freopen stderr", NULL, MB_OK);
2434-
if (!freopen(tempname, "a", stdout))
2435-
MessageBox(GetFocus(), "freopen stdout", NULL, MB_OK);
2436-
2437-
hPython = LoadLibrary(dllname);
2438-
if (hPython) {
2439-
if (0x80000000 == run_installscript(hPython, scriptname, 2, argv))
2440-
fprintf(stderr, "*** Could not load Python ***");
2441-
FreeLibrary(hPython);
2442-
}
2443-
2444-
fflush(stderr);
2445-
fclose(stderr);
2446-
fflush(stdout);
2447-
fclose(stdout);
2448-
2449-
fp = fopen(tempname, "rb");
2450-
n = fread(buffer, 1, sizeof(buffer), fp);
2451-
fclose(fp);
2452-
remove(tempname);
2453-
2454-
buffer[n] = '\0';
2455-
if (buffer[0])
2455+
if (buffer && buffer[0])
24562456
MessageBox(GetFocus(), buffer, "uninstall-script", MB_OK);
2457+
free(buffer);
24572458

24582459
strcpy(lastscript, scriptname);
24592460
}

PCbuild/bdist_wininst.vcproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
AdditionalIncludeDirectories="..\PC\bdist_wininst;..\Include;..\Modules\zlib"
5656
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
5757
StringPooling="true"
58-
RuntimeLibrary="2"
58+
RuntimeLibrary="0"
5959
EnableFunctionLevelLinking="true"
6060
WarningLevel="3"
6161
SuppressStartupBanner="true"
@@ -145,7 +145,7 @@
145145
AdditionalIncludeDirectories="..\PC\bdist_wininst;..\Include;..\Modules\zlib"
146146
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
147147
StringPooling="true"
148-
RuntimeLibrary="2"
148+
RuntimeLibrary="0"
149149
EnableFunctionLevelLinking="true"
150150
WarningLevel="3"
151151
SuppressStartupBanner="true"

0 commit comments

Comments
 (0)