@@ -694,8 +694,9 @@ static int prepare_script_environment(HINSTANCE hPython)
694694 */
695695
696696static 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)
781829static 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 }
0 commit comments