0026179: Coding rules - eliminate -Wdeprecated-declarations CLang warnings on tmpnam...
authorrkv <rkv@opencascade.com>
Mon, 16 Nov 2015 14:43:25 +0000 (17:43 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 19 Nov 2015 12:31:17 +0000 (15:31 +0300)
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
src/OSD/OSD_Directory.cxx
src/OSD/OSD_File.cxx
src/OSD/OSD_File.hxx

index fef27ed..ba6335b 100644 (file)
@@ -26,6 +26,7 @@
 #include <OSD_Process.hxx>
 #include <OSD_Path.hxx>
 #include <OSD.hxx>
+#include <OSD_File.hxx>
 
 #include <string.h>
 #include <tcl.h>
@@ -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
index ed5c03c..2415f4f 100644 (file)
@@ -14,7 +14,6 @@
 
 #ifndef _WIN32
 
-
 #include <OSD_Directory.hxx>
 #include <OSD_Path.hxx>
 #include <OSD_Protection.hxx>
@@ -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;
 
index 94a451b..0e6fdc5 100644 (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)
  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<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
 #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()
 
 
 
-
index 2cc055f..4ecc16a 100644 (file)
@@ -92,6 +92,23 @@ public:
   //! bytes actually read into <NByteRead> and placed into the
   //! Buffer <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 <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
   //! 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: