1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-21 10:13:43 +03:00

0026179: Coding rules - eliminate -Wdeprecated-declarations CLang warnings on tmpnam() usage

Make a temporary file using BuildTemporary() in "/tmp" folder on Linux or using "TEMP" environment variable on Windows.
Use the new OSD_File::Capture() method for standard output redirection.
This commit is contained in:
rkv 2015-11-16 17:43:25 +03:00 committed by bugmaster
parent 9b7f3f83c0
commit 95e05159d6
4 changed files with 136 additions and 76 deletions

View File

@ -26,6 +26,7 @@
#include <OSD_Process.hxx> #include <OSD_Process.hxx>
#include <OSD_Path.hxx> #include <OSD_Path.hxx>
#include <OSD.hxx> #include <OSD.hxx>
#include <OSD_File.hxx>
#include <string.h> #include <string.h>
#include <tcl.h> #include <tcl.h>
@ -66,39 +67,20 @@ namespace {
cout << flush; cout << flush;
} }
FILE* capture_start (int std_fd, int *save_fd, char*& tmp_name) int capture_start (OSD_File& theTmpFile, int std_fd)
{ {
*save_fd = 0; theTmpFile.BuildTemporary();
if (theTmpFile.Failed())
// open temporary files
#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; cerr << "Error: cannot create temporary file for capturing console output" << endl;
fclose (aTmpFile); return -1;
return NULL;
} }
// remember current file descriptors of standard stream, and replace it by temporary // remember current file descriptors of standard stream, and replace it by temporary
(*save_fd) = dup(std_fd); return theTmpFile.Capture(std_fd);
dup2(fd_tmp, std_fd);
return aTmpFile;
} }
void capture_end (FILE* tmp_file, int std_fd, int save_fd, char* tmp_name, Standard_OStream &log, Standard_Boolean doEcho) void capture_end (OSD_File* tmp_file, int std_fd, int save_fd, Standard_OStream &log, Standard_Boolean doEcho)
{ {
if (!tmp_file) if (!tmp_file)
return; return;
@ -109,9 +91,9 @@ namespace {
// extract all output and copy it to log and optionally to cout // extract all output and copy it to log and optionally to cout
const int BUFSIZE = 2048; const int BUFSIZE = 2048;
char buf[BUFSIZE]; TCollection_AsciiString buf;
rewind(tmp_file); tmp_file->Rewind();
while (fgets (buf, BUFSIZE, tmp_file) != NULL) while (tmp_file->ReadLine (buf, BUFSIZE) > 0)
{ {
log << buf; log << buf;
if (doEcho) if (doEcho)
@ -119,12 +101,13 @@ namespace {
} }
// close temporary file // close temporary file
fclose (tmp_file); tmp_file->Close();
// remove temporary file if this is not done by the system // remove temporary file if this is not done by the system
if (tmp_name) if (tmp_file->Exists())
remove (tmp_name); tmp_file->Remove();
} }
}; };
// MKV 29.03.05 // MKV 29.03.05
@ -157,15 +140,13 @@ static Standard_Integer CommandCmd
flush_standard_streams(); flush_standard_streams();
// capture cout and cerr to log // capture cout and cerr to log
char *err_name = NULL, *out_name = NULL; OSD_File aFile_out, aFile_err;
FILE * aFile_err = NULL; int fd_err_save = -1;
FILE * aFile_out = NULL; int fd_out_save = -1;
int fd_err_save = 0;
int fd_out_save = 0;
if (doLog) if (doLog)
{ {
aFile_out = capture_start (STDOUT_FILENO, &fd_out_save, out_name); fd_out_save = capture_start (aFile_out, STDOUT_FILENO);
aFile_err = capture_start (STDERR_FILENO, &fd_err_save, err_name); fd_err_save = capture_start (aFile_err, STDERR_FILENO);
} }
// run command // run command
@ -218,8 +199,8 @@ static Standard_Integer CommandCmd
// end capturing cout and cerr // end capturing cout and cerr
if (doLog) if (doLog)
{ {
capture_end (aFile_err, STDERR_FILENO, fd_err_save, err_name, di.Log(), doEcho); capture_end (&aFile_err, STDERR_FILENO, fd_err_save, di.Log(), doEcho);
capture_end (aFile_out, STDOUT_FILENO, fd_out_save, out_name, di.Log(), doEcho); capture_end (&aFile_out, STDOUT_FILENO, fd_out_save, di.Log(), doEcho);
} }
// log command result // log command result

View File

@ -14,7 +14,6 @@
#ifndef _WIN32 #ifndef _WIN32
#include <OSD_Directory.hxx> #include <OSD_Directory.hxx>
#include <OSD_Path.hxx> #include <OSD_Path.hxx>
#include <OSD_Protection.hxx> #include <OSD_Protection.hxx>
@ -59,19 +58,17 @@ TCollection_AsciiString aBuffer;
} }
OSD_Directory OSD_Directory::BuildTemporary(){ OSD_Directory OSD_Directory::BuildTemporary(){
OSD_Protection Protect;
OSD_Directory aDirectoryToReturn; OSD_Directory aDirectoryToReturn;
Standard_Integer internal_prot; char name[] = "/tmp/CSFXXXXXX";
Standard_CString name = tmpnam(NULL);
TCollection_AsciiString aString (name);
internal_prot = Protect.Internal(); // Create a temporary directory with 0700 permissions.
if (NULL == mkdtemp( name ))
return aDirectoryToReturn; // Can't create a directory
umask ( 0 );
mkdir (name, (mode_t)internal_prot);
unlink(name);//Destroys link but directory still exists while unlink(name);//Destroys link but directory still exists while
//current process lives. //current process lives.
TCollection_AsciiString aString (name);
aDirectoryToReturn.SetPath ( aString ); aDirectoryToReturn.SetPath ( aString );
return aDirectoryToReturn; return aDirectoryToReturn;

View File

@ -241,38 +241,35 @@ void OSD_File::Open(const OSD_OpenMode Mode,
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
OSD_File OSD_File::BuildTemporary(){ void OSD_File::BuildTemporary(){
if ( IsOpen() )
Close();
#if defined(vax) || defined(__vms) || defined(VAXVMS) #if defined(vax) || defined(__vms) || defined(VAXVMS)
FILE *fic; FILE *fic;
OSD_File result;
int dummy; int dummy;
fic = tmpfile(); fic = tmpfile();
dummy = open("dummy", O_RDWR | O_CREAT); // Open a dummy file dummy = open("dummy", O_RDWR | O_CREAT); // Open a dummy file
result.myFileChannel = dummy - 1; // This is file channel of "fic" +1 myFileChannel = dummy - 1; // This is file channel of "fic" +1
close(dummy); // Close dummy file close(dummy); // Close dummy file
unlink("dummy"); // Removes dummy file unlink("dummy"); // Removes dummy file
#else #else
OSD_File result; char name[] = "/tmp/CSFXXXXXX";
char *name = tmpnam((char*) 0) ; myFileChannel = mkstemp( name );
TCollection_AsciiString aName ( name ) ; TCollection_AsciiString aName ( name ) ;
OSD_Path aPath( aName ) ; OSD_Path aPath( aName ) ;
result.SetPath( aPath ) ; SetPath( aPath ) ;
result.myFILE = fopen( name, "w+" ) ; myFILE = fdopen( myFileChannel, "w+" ) ;
result.myFileChannel = fileno( (FILE*)result.myFILE );
#endif #endif
result.myMode = OSD_ReadWrite; myMode = OSD_ReadWrite;
return (result);
} }
@ -804,6 +801,20 @@ Standard_Boolean OSD_File::IsExecutable()
return Standard_True; return Standard_True;
} }
int OSD_File::Capture(int theDescr) {
// Duplicate an old file descriptor of the given one to be able to restore output to it later.
int oldDescr = dup(theDescr);
// Redirect the output to this file
dup2(myFileChannel, theDescr);
// Return the old descriptor
return oldDescr;
}
void OSD_File::Rewind() {
rewind((FILE*)myFILE);
}
#else /* _WIN32 */ #else /* _WIN32 */
//------------------------------------------------------------------------ //------------------------------------------------------------------------
@ -893,6 +904,46 @@ OSD_File :: OSD_File ( const OSD_Path& Name ) : OSD_FileNode ( Name )
myFileHandle = INVALID_HANDLE_VALUE; myFileHandle = INVALID_HANDLE_VALUE;
} // end constructor ( 2 ) } // end constructor ( 2 )
// ---------------------------------------------------------------------
// Redirect a standard handle (fileno(stdout), fileno(stdin) or
// fileno(stderr) to this OSD_File and return the copy of the original
// standard handle.
// Example:
// OSD_File aTmp;
// aTmp.BuildTemporary();
// int stdfd = _fileno(stdout);
//
// int oldout = aTmp.Capture(stdfd);
// cout << "Some output to the file" << endl;
// cout << flush;
// fflush(stdout);
//
// _dup2(oldout, stdfd); // Restore standard output
// aTmp.Close();
// ---------------------------------------------------------------------
int OSD_File::Capture(int theDescr) {
// Get POSIX file descriptor from this file handle
int dFile = _open_osfhandle(reinterpret_cast<intptr_t>(myFileHandle), myMode);
if (0 > dFile)
{
_osd_wnt_set_error ( myError, OSD_WFile, myFileHandle );
return -1;
}
// Duplicate an old file descriptor of the given one to be able to restore output to it later.
int oldDescr = _dup(theDescr);
// Redirect the output to this file
_dup2(dFile, theDescr);
// Return the old descriptor
return oldDescr;
}
void OSD_File::Rewind() {
SetFilePointer( myFileHandle, 0, NULL, FILE_BEGIN );
}
// protect against occasional use of myFileHande in Windows code // protect against occasional use of myFileHande in Windows code
#define myFileChannel myFileChannel_is_only_for_Linux #define myFileChannel myFileChannel_is_only_for_Linux
@ -1429,10 +1480,9 @@ typedef struct _osd_wnt_key {
} OSD_WNT_KEY; } OSD_WNT_KEY;
OSD_File OSD_File :: BuildTemporary () { void OSD_File::BuildTemporary () {
OSD_Protection prt; OSD_Protection prt;
OSD_File retVal;
HKEY hKey; HKEY hKey;
TCHAR tmpPath[ MAX_PATH ]; TCHAR tmpPath[ MAX_PATH ];
BOOL fOK = FALSE; BOOL fOK = FALSE;
@ -1494,11 +1544,11 @@ OSD_File OSD_File :: BuildTemporary () {
GetTempFileName ( tmpPath, "CSF", 0, tmpPath ); GetTempFileName ( tmpPath, "CSF", 0, tmpPath );
retVal.SetPath ( OSD_Path ( tmpPath ) ); if ( IsOpen() )
retVal.Build ( OSD_ReadWrite, prt ); Close();
return retVal;
SetPath ( OSD_Path ( tmpPath ) );
Build ( OSD_ReadWrite, prt );
} // end OSD_File :: BuildTemporary } // end OSD_File :: BuildTemporary
//-------------------------------------------------finpri???980424 //-------------------------------------------------finpri???980424
@ -2863,4 +2913,3 @@ Standard_Boolean OSD_File::Edit()

View File

@ -93,6 +93,23 @@ public:
//! Buffer <Buffer>. //! Buffer <Buffer>.
Standard_EXPORT void ReadLine (TCollection_AsciiString& Buffer, const Standard_Integer NByte, Standard_Integer& NbyteRead); Standard_EXPORT void ReadLine (TCollection_AsciiString& Buffer, const Standard_Integer NByte, Standard_Integer& NbyteRead);
//! Reads bytes from the data pointed to by the object file
//! into the buffer <Buffer>.
//! Data is read until <NByte-1> bytes have been read,
//! until a newline character is read and transferred into
//! <Buffer>, or until an EOF (End-of-File) condition is
//! encountered.
//! Upon successful completion, Read returns the number of
//! bytes actually read and placed into the Buffer <Buffer>.
inline Standard_Integer ReadLine (
TCollection_AsciiString& Buffer, const Standard_Integer NByte)
{
Standard_Integer NbyteRead;
ReadLine(Buffer, NByte, NbyteRead);
return NbyteRead;
}
//! Attempts to read Nbyte bytes from the files associated with //! Attempts to read Nbyte bytes from the files associated with
//! the object File. //! the object File.
//! Upon successful completion, Read returns the number of //! Upon successful completion, Read returns the number of
@ -124,10 +141,8 @@ public:
Standard_EXPORT OSD_KindFile KindOfFile() const; Standard_EXPORT OSD_KindFile KindOfFile() const;
//! Makes a temporary File //! Makes a temporary File
//! This returned file is already open ! //! This temporary file is already open !
//! This file is non-persistent and will be automatically Standard_EXPORT void BuildTemporary();
//! removed when its process finishes.
Standard_EXPORT static OSD_File BuildTemporary();
//! Locks current file //! Locks current file
Standard_EXPORT void SetLock (const OSD_LockType Lock); Standard_EXPORT void SetLock (const OSD_LockType Lock);
@ -171,7 +186,25 @@ public:
//! find an editor on the system and edit the given file //! find an editor on the system and edit the given file
Standard_EXPORT Standard_Boolean Edit(); Standard_EXPORT Standard_Boolean Edit();
//! Set file pointer position to the beginning of the file
Standard_EXPORT void Rewind();
//! Redirect a standard handle (fileno(stdout), fileno(stdin) or
//! fileno(stderr) to this OSD_File and return the copy of the original
//! standard handle.
//! Example:
//! OSD_File aTmp;
//! aTmp.BuildTemporary();
//! int stdfd = _fileno(stdout);
//!
//! int oldout = aTmp.Capture(stdfd);
//! cout << "Some output to the file" << endl;
//! cout << flush;
//! fflush(stdout);
//!
//! _dup2(oldout, stdfd); // Restore standard output
//! aTmp.Close();
Standard_EXPORT int Capture(int theDescr);
protected: protected: