From 0a559644c385a5d15fd333e96d581643ca3e6255 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= <klinkjak@fjfi.cvut.cz>
Date: Fri, 5 May 2017 19:00:35 +0200
Subject: [PATCH] The File class should close itself from the destructor

Doing this in a destructor is the only place where we can guarantee that
no open file descriptors will be left behind.
---
 src/TNL/File.cpp   | 13 +++++++++++++
 src/TNL/File.h     |  2 ++
 src/TNL/Object.cpp | 23 ++++-------------------
 3 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/src/TNL/File.cpp b/src/TNL/File.cpp
index d6e16b17ac..3b5fe35141 100644
--- a/src/TNL/File.cpp
+++ b/src/TNL/File.cpp
@@ -23,6 +23,14 @@ File :: File()
 {
 }
 
+File :: ~File()
+{
+   // destroying a file without closing is a memory leak
+   // (an open file descriptor is left behind, on Linux there is typically
+   // only a limited number of descriptors available to each process)
+   close();
+}
+
 bool File :: open( const String& fileName,
                       const tnlIOMode mode )
 {
@@ -60,6 +68,11 @@ bool File :: close()
       std::cerr << "I was not able to close the file " << fileName << " properly!" << std::endl;
       return false;
    }
+   // reset all attributes
+   mode = tnlUndefinedMode;
+   file = NULL;
+   fileOK = false;
+   fileName = "";
    readElements = writtenElements = 0;
    return true;
 };
diff --git a/src/TNL/File.h b/src/TNL/File.h
index 1eea42eae6..67a81b8b82 100644
--- a/src/TNL/File.h
+++ b/src/TNL/File.h
@@ -57,6 +57,8 @@ class File
 
    File();
 
+   ~File();
+
    bool open( const String& fileName,
               const tnlIOMode mode );
 
diff --git a/src/TNL/Object.cpp b/src/TNL/Object.cpp
index 74a4bbb7a1..b3ad74f10a 100644
--- a/src/TNL/Object.cpp
+++ b/src/TNL/Object.cpp
@@ -85,10 +85,7 @@ bool Object :: save( const String& fileName ) const
       std::cerr << "I am not bale to open the file " << fileName << " for writing." << std::endl;
       return false;
    }
-   const bool status = this->save( file );
-   if( ! file. close() )
-      std::cerr << "An error occurred when I was closing the file " << fileName << "." << std::endl;
-   return status;
+   return this->save( file );
 }
 
 bool Object :: load( const String& fileName )
@@ -99,10 +96,7 @@ bool Object :: load( const String& fileName )
       std::cerr << "I am not bale to open the file " << fileName << " for reading." << std::endl;
       return false;
    }
-   const bool status = this->load( file );
-   if( ! file. close() )
-      std::cerr << "An error occurred when I was closing the file " << fileName << "." << std::endl;
-   return status;
+   return this->load( file );
 }
 
 bool Object :: boundLoad( const String& fileName )
@@ -113,14 +107,7 @@ bool Object :: boundLoad( const String& fileName )
       std::cerr << "I am not bale to open the file " << fileName << " for reading." << std::endl;
       return false;
    }
-   if( ! this->boundLoad( file ) )
-      return false;
-   if( ! file. close() )
-   {
-      std::cerr << "An error occurred when I was closing the file " << fileName << "." << std::endl;
-      return false;
-   }
-   return true;
+   return this->boundLoad( file );
 }
 
 void Object::setDeprecatedReadMode()
@@ -155,9 +142,7 @@ bool getObjectType( const String& fileName, String& type )
       std::cerr << "I am not able to open the file " << fileName << " for detecting the object inside!" << std::endl;
       return false;
    }
-   bool ret_val = getObjectType( binaryFile, type );
-   binaryFile. close();
-   return ret_val;
+   return getObjectType( binaryFile, type );
 }
 
 bool parseObjectType( const String& objectType,
-- 
GitLab