Windows: Redirect stdout/stderr to NUL instead of temp files. Avoids unnecessary creation of temp files

This commit is contained in:
Kovid Goyal 2014-11-13 10:56:53 +05:30
parent a7899be02d
commit d0a44763f8
3 changed files with 15 additions and 41 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);