diff --git a/src/Draw/Draw_Interpretor.cxx b/src/Draw/Draw_Interpretor.cxx index 41fa96e0e3..540985205f 100755 --- a/src/Draw/Draw_Interpretor.cxx +++ b/src/Draw/Draw_Interpretor.cxx @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -120,15 +121,26 @@ namespace { cout << flush; } - FILE* capture_start (int std_fd, int *save_fd) + FILE* capture_start (int std_fd, int *save_fd, char*& tmp_name) { - (*save_fd) = 0; + *save_fd = 0; // open temporary files - FILE * aTmpFile = tmpfile(); - int fd_tmp = fileno(aTmpFile); - - if (fd_tmp <0) + #if defined(_WIN32) + // use _tempnam() to decrease chances of failure (tmpfile() creates + // file in root folder and will fail if it is write protected), see #24132 + static const char* tmpdir = getenv("TEMP"); + static char prefix[256] = ""; // prefix for temporary files, initialize once per process using pid + if (prefix[0] == '\0') + sprintf (prefix, "drawtmp%d_", (int)OSD_Process().ProcessId()); + tmp_name = _tempnam (tmpdir, prefix); + FILE* aTmpFile = (tmp_name != NULL ? fopen (tmp_name, "w+b") : tmpfile()); + #else + tmp_name = NULL; + FILE* aTmpFile = tmpfile(); + #endif + int fd_tmp = (aTmpFile != NULL ? fileno (aTmpFile) : -1); + if (fd_tmp < 0) { cerr << "Error: cannot create temporary file for capturing console output" << endl; fclose (aTmpFile); @@ -141,8 +153,11 @@ namespace { return aTmpFile; } - void capture_end (FILE* tmp_file, int std_fd, int save_fd, Standard_OStream &log, Standard_Boolean doEcho) + void capture_end (FILE* tmp_file, int std_fd, int save_fd, char* tmp_name, Standard_OStream &log, Standard_Boolean doEcho) { + if (! tmp_file) + return; + // restore normal descriptors of console stream dup2 (save_fd, std_fd); close(save_fd); @@ -160,6 +175,10 @@ namespace { // close temporary file fclose (tmp_file); + + // remove temporary file if this is not done by the system + if (tmp_name) + remove (tmp_name); } }; @@ -193,14 +212,15 @@ static Standard_Integer CommandCmd flush_standard_streams(); // capture cout and cerr to log + char *err_name = NULL, *out_name = NULL; FILE * aFile_err = NULL; FILE * aFile_out = NULL; int fd_err_save = 0; int fd_out_save = 0; if (doLog) { - aFile_out = capture_start (STDOUT_FILENO, &fd_out_save); - aFile_err = capture_start (STDERR_FILENO, &fd_err_save); + aFile_out = capture_start (STDOUT_FILENO, &fd_out_save, out_name); + aFile_err = capture_start (STDERR_FILENO, &fd_err_save, err_name); } // run command @@ -258,8 +278,8 @@ static Standard_Integer CommandCmd // end capturing cout and cerr if (doLog) { - capture_end (aFile_err, STDERR_FILENO, fd_err_save, di.Log(), doEcho); - capture_end (aFile_out, STDOUT_FILENO, fd_out_save, di.Log(), doEcho); + capture_end (aFile_err, STDERR_FILENO, fd_err_save, err_name, di.Log(), doEcho); + capture_end (aFile_out, STDOUT_FILENO, fd_out_save, out_name, di.Log(), doEcho); } // log command result