#include <TCollection_AsciiString.hxx>
#include <TCollection_ExtendedString.hxx>
+#include <OSD_Process.hxx>
#include <OSD_Path.hxx>
#include <OSD.hxx>
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);
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);
// close temporary file
fclose (tmp_file);
+
+ // remove temporary file if this is not done by the system
+ if (tmp_name)
+ remove (tmp_name);
}
};
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
// 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