From e9b037efd2ff768d6666d6fd8cabfa059ceebdfe Mon Sep 17 00:00:00 2001 From: kgv Date: Thu, 5 Sep 2013 13:11:45 +0400 Subject: [PATCH] 0024132: Test execution fails due to permission rights issues Generation of temporary files used for capturing DRAW command output on Windows is improved to use directory specified by environment variable TMP or TEMP (instead of root directory which can be write-protected) --- src/Draw/Draw_Interpretor.cxx | 42 ++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 11 deletions(-) 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