From d0a44763f80f1d203a8510da88f78c4055f77e15 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 13 Nov 2014 10:56:53 +0530 Subject: [PATCH] Windows: Redirect stdout/stderr to NUL instead of temp files. Avoids unnecessary creation of temp files --- setup/installer/windows/main.c | 23 ++++++----------------- setup/installer/windows/util.c | 24 ++++++------------------ setup/installer/windows/util.h | 9 +++------ 3 files changed, 15 insertions(+), 41 deletions(-) diff --git a/setup/installer/windows/main.c b/setup/installer/windows/main.c index 56a022cb97..07b4e8ab0d 100644 --- a/setup/installer/windows/main.c +++ b/setup/installer/windows/main.c @@ -7,26 +7,15 @@ #ifdef GUI_APP int WINAPI -wWinMain(HINSTANCE Inst, HINSTANCE PrevInst, - wchar_t *CmdLine, int CmdShow) { - - wchar_t *stdout_redirect, *stderr_redirect, basename[50]; - +wWinMain(HINSTANCE Inst, HINSTANCE PrevInst, wchar_t *CmdLine, int CmdShow) { set_gui_app((char)1); - MultiByteToWideChar(CP_UTF8, 0, BASENAME, -1, basename, 50); + // Redirect stdout and stderr to NUL so that python does not fail writing to them + redirect_out_stream(stdout); + redirect_out_stream(stderr); - stdout_redirect = redirect_out_stream(basename, (char)1); - stderr_redirect = redirect_out_stream(basename, (char)0); + execute_python_entrypoint(BASENAME, MODULE, FUNCTION); - execute_python_entrypoint(BASENAME, MODULE, FUNCTION, - stdout_redirect, stderr_redirect); - - if (stdout != NULL) fclose(stdout); - if (stderr != NULL) fclose(stderr); - - DeleteFile(stdout_redirect); - DeleteFile(stderr_redirect); return 0; // This should really be returning the value set in the WM_QUIT message, but I cannot be bothered figuring out how to get that. } @@ -37,7 +26,7 @@ wWinMain(HINSTANCE Inst, HINSTANCE PrevInst, int wmain(int argc, wchar_t *argv) { int ret = 0; set_gui_app((char)0); - ret = execute_python_entrypoint(BASENAME, MODULE, FUNCTION, NULL, NULL); + ret = execute_python_entrypoint(BASENAME, MODULE, FUNCTION); return ret; } diff --git a/setup/installer/windows/util.c b/setup/installer/windows/util.c index 4be1081e71..86a9d22c30 100644 --- a/setup/installer/windows/util.c +++ b/setup/installer/windows/util.c @@ -276,8 +276,7 @@ void setup_streams() { setup_stream("stderr", "strict", CP_UTF8); } -void initialize_interpreter(wchar_t *outr, wchar_t *errr, - const char *basename, const char *module, const char *function) { +void initialize_interpreter(const char *basename, const char *module, const char *function) { DWORD sz; char *buf, *path; HMODULE dll; int *flag, i, argc; wchar_t *app_dir, **wargv; @@ -353,11 +352,6 @@ void initialize_interpreter(wchar_t *outr, wchar_t *errr, PySys_SetObject("calibre_module", PyBytes_FromString(module)); PySys_SetObject("calibre_function", PyBytes_FromString(function)); - if (GUI_APP && outr && errr) { - PySys_SetObject("stdout_redirect", PyUnicode_FromWideChar(outr, wcslen(outr))); - PySys_SetObject("stderr_redirect", PyUnicode_FromWideChar(errr, wcslen(outr))); - } - wargv = CommandLineToArgvW(GetCommandLineW(), &argc); if (wargv == NULL) ExitProcess(show_last_error(L"Failed to get command line")); argv = PyList_New(argc); @@ -450,13 +444,12 @@ int calibre_show_python_error(const wchar_t *preamble, int code) { return _show_error(preamble, L"", code); } -int execute_python_entrypoint(const char *basename, const char *module, const char *function, - wchar_t *outr, wchar_t *errr) { +int execute_python_entrypoint(const char *basename, const char *module, const char *function) { PyObject *site, *main, *res; int ret = 0; load_python_dll(); - initialize_interpreter(outr, errr, basename, module, function); + initialize_interpreter(basename, module, function); site = PyImport_ImportModule("site"); @@ -511,18 +504,13 @@ wchar_t* get_temp_filename(const wchar_t *prefix) { return szTempName; } -wchar_t* redirect_out_stream(const wchar_t *prefix, char outstream) { +void redirect_out_stream(FILE *stream) { FILE *f = NULL; wchar_t *temp_file; errno_t err; - temp_file = get_temp_filename(prefix); - - err = _wfreopen_s(&f, temp_file, L"a+t", (outstream) ? stdout : stderr); + err = freopen_s(&f, "NUL", "wt", stream); if (err != 0) { - ExitProcess(show_last_error_crt(L"Failed to redirect stdout.")); + ExitProcess(show_last_error_crt(L"Failed to redirect stdout/stderr to NUL. This indicates a corrupted Windows install.\r\n You should contact Microsoft for assistance and/or follow the steps described here:\r\n http://bytes.com/topic/net/answers/264804-compile-error-null-device-missing")); } - - return temp_file; - } diff --git a/setup/installer/windows/util.h b/setup/installer/windows/util.h index dcdbc36601..ff3ee6f943 100644 --- a/setup/installer/windows/util.h +++ b/setup/installer/windows/util.h @@ -37,12 +37,9 @@ ExIm void set_gui_app(char yes); ExIm char is_gui_app(); -// Redirect output streams to a temporary file -// The temporary file name is returned it should be -// free'ed with LocalFree -// If outstream is true redirects stdout, otherwise redirects stderr -ExIm wchar_t* redirect_out_stream(const wchar_t *prefix, char outstream); +// Redirect output streams to NUL +ExIm void redirect_out_stream(FILE *stream); // Execute python entry point defined by: module and function -ExIm int execute_python_entrypoint(const char *basename, const char *module, const char *function, wchar_t *stdout_redirect, wchar_t *stderr_redirect); +ExIm int execute_python_entrypoint(const char *basename, const char *module, const char *function);