From 95e05159d6a0cdaed7f8a15fd5dca322549f817a Mon Sep 17 00:00:00 2001 From: rkv Date: Mon, 16 Nov 2015 17:43:25 +0300 Subject: [PATCH] 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. --- src/Draw/Draw_Interpretor.cxx | 65 +++++++++---------------- src/OSD/OSD_Directory.cxx | 17 +++---- src/OSD/OSD_File.cxx | 89 +++++++++++++++++++++++++++-------- src/OSD/OSD_File.hxx | 43 +++++++++++++++-- 4 files changed, 137 insertions(+), 77 deletions(-) diff --git a/src/Draw/Draw_Interpretor.cxx b/src/Draw/Draw_Interpretor.cxx index fef27edd73..ba6335b5fa 100644 --- a/src/Draw/Draw_Interpretor.cxx +++ b/src/Draw/Draw_Interpretor.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -66,52 +67,33 @@ namespace { 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; - - // 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) + theTmpFile.BuildTemporary(); + if (theTmpFile.Failed()) { cerr << "Error: cannot create temporary file for capturing console output" << endl; - fclose (aTmpFile); - return NULL; + return -1; } // remember current file descriptors of standard stream, and replace it by temporary - (*save_fd) = dup(std_fd); - dup2(fd_tmp, std_fd); - return aTmpFile; + return theTmpFile.Capture(std_fd); } - 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; // restore normal descriptors of console stream - dup2 (save_fd, std_fd); + dup2(save_fd, std_fd); close(save_fd); // extract all output and copy it to log and optionally to cout const int BUFSIZE = 2048; - char buf[BUFSIZE]; - rewind(tmp_file); - while (fgets (buf, BUFSIZE, tmp_file) != NULL) + TCollection_AsciiString buf; + tmp_file->Rewind(); + while (tmp_file->ReadLine (buf, BUFSIZE) > 0) { log << buf; if (doEcho) @@ -119,12 +101,13 @@ namespace { } // close temporary file - fclose (tmp_file); + tmp_file->Close(); // remove temporary file if this is not done by the system - if (tmp_name) - remove (tmp_name); + if (tmp_file->Exists()) + tmp_file->Remove(); } + }; // MKV 29.03.05 @@ -157,15 +140,13 @@ 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; + OSD_File aFile_out, aFile_err; + int fd_err_save = -1; + int fd_out_save = -1; if (doLog) { - aFile_out = capture_start (STDOUT_FILENO, &fd_out_save, out_name); - aFile_err = capture_start (STDERR_FILENO, &fd_err_save, err_name); + fd_out_save = capture_start (aFile_out, STDOUT_FILENO); + fd_err_save = capture_start (aFile_err, STDERR_FILENO); } // run command @@ -218,8 +199,8 @@ static Standard_Integer CommandCmd // end capturing cout and cerr if (doLog) { - 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); + capture_end (&aFile_err, STDERR_FILENO, fd_err_save, di.Log(), doEcho); + capture_end (&aFile_out, STDOUT_FILENO, fd_out_save, di.Log(), doEcho); } // log command result diff --git a/src/OSD/OSD_Directory.cxx b/src/OSD/OSD_Directory.cxx index ed5c03c9de..2415f4f998 100644 --- a/src/OSD/OSD_Directory.cxx +++ b/src/OSD/OSD_Directory.cxx @@ -14,7 +14,6 @@ #ifndef _WIN32 - #include #include #include @@ -59,19 +58,17 @@ TCollection_AsciiString aBuffer; } OSD_Directory OSD_Directory::BuildTemporary(){ -OSD_Protection Protect; OSD_Directory aDirectoryToReturn; -Standard_Integer internal_prot; -Standard_CString name = tmpnam(NULL); -TCollection_AsciiString aString (name); - - internal_prot = Protect.Internal(); +char name[] = "/tmp/CSFXXXXXX"; - umask ( 0 ); - mkdir (name, (mode_t)internal_prot); - unlink(name);//Destroys link but directory still exists while + // Create a temporary directory with 0700 permissions. + if (NULL == mkdtemp( name )) + return aDirectoryToReturn; // Can't create a directory + + unlink(name);//Destroys link but directory still exists while //current process lives. + TCollection_AsciiString aString (name); aDirectoryToReturn.SetPath ( aString ); return aDirectoryToReturn; diff --git a/src/OSD/OSD_File.cxx b/src/OSD/OSD_File.cxx index 94a451be46..0e6fdc5f50 100644 --- a/src/OSD/OSD_File.cxx +++ b/src/OSD/OSD_File.cxx @@ -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) FILE *fic; - OSD_File result; int dummy; fic = tmpfile(); 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 unlink("dummy"); // Removes dummy file #else - OSD_File result; - char *name = tmpnam((char*) 0) ; - + char name[] = "/tmp/CSFXXXXXX"; + myFileChannel = mkstemp( name ); TCollection_AsciiString aName ( name ) ; OSD_Path aPath( aName ) ; - result.SetPath( aPath ) ; + SetPath( aPath ) ; - result.myFILE = fopen( name, "w+" ) ; - - result.myFileChannel = fileno( (FILE*)result.myFILE ); + myFILE = fdopen( myFileChannel, "w+" ) ; #endif - result.myMode = OSD_ReadWrite; - - return (result); + myMode = OSD_ReadWrite; } @@ -804,6 +801,20 @@ Standard_Boolean OSD_File::IsExecutable() 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 */ //------------------------------------------------------------------------ @@ -893,6 +904,46 @@ OSD_File :: OSD_File ( const OSD_Path& Name ) : OSD_FileNode ( Name ) myFileHandle = INVALID_HANDLE_VALUE; } // 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(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 #define myFileChannel myFileChannel_is_only_for_Linux @@ -1429,10 +1480,9 @@ typedef struct _osd_wnt_key { } OSD_WNT_KEY; -OSD_File OSD_File :: BuildTemporary () { + void OSD_File::BuildTemporary () { OSD_Protection prt; - OSD_File retVal; HKEY hKey; TCHAR tmpPath[ MAX_PATH ]; BOOL fOK = FALSE; @@ -1494,11 +1544,11 @@ OSD_File OSD_File :: BuildTemporary () { GetTempFileName ( tmpPath, "CSF", 0, tmpPath ); - retVal.SetPath ( OSD_Path ( tmpPath ) ); - retVal.Build ( OSD_ReadWrite, prt ); - - return retVal; + if ( IsOpen() ) + Close(); + SetPath ( OSD_Path ( tmpPath ) ); + Build ( OSD_ReadWrite, prt ); } // end OSD_File :: BuildTemporary //-------------------------------------------------finpri???980424 @@ -2863,4 +2913,3 @@ Standard_Boolean OSD_File::Edit() - diff --git a/src/OSD/OSD_File.hxx b/src/OSD/OSD_File.hxx index 2cc055f91a..4ecc16a5e0 100644 --- a/src/OSD/OSD_File.hxx +++ b/src/OSD/OSD_File.hxx @@ -92,6 +92,23 @@ public: //! bytes actually read into and placed into the //! Buffer . 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 . + //! Data is read until bytes have been read, + //! until a newline character is read and transferred into + //! , 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 . + 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 //! the object File. @@ -124,10 +141,8 @@ public: Standard_EXPORT OSD_KindFile KindOfFile() const; //! Makes a temporary File - //! This returned file is already open ! - //! This file is non-persistent and will be automatically - //! removed when its process finishes. - Standard_EXPORT static OSD_File BuildTemporary(); + //! This temporary file is already open ! + Standard_EXPORT void BuildTemporary(); //! Locks current file Standard_EXPORT void SetLock (const OSD_LockType Lock); @@ -171,7 +186,25 @@ public: //! find an editor on the system and edit the given file 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: -- 2.20.1