diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index b4ba548d211146a66218f575cdc52fdaec5dd8b9..1167c668ab0fcae6f3bb85690b63d2e5eefefa5a 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -1,6 +1,7 @@
 cmake_minimum_required (VERSION 2.6)
 
 set (COMMON_LIB_SRC_FILES
+  SmartFd.cpp
   Timer.cpp
   Utils.cpp
   exception/Backtrace.cpp
@@ -20,6 +21,7 @@ target_link_libraries (ctacommon
   uuid)
 
 set (COMMON_UNIT_TESTS_LIB_SRC_FILES
+  SmartFdTest.cpp
   UtilsTest.cpp)
 
 add_library (ctacommonunittests SHARED
diff --git a/common/SmartFd.cpp b/common/SmartFd.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4b58df0bac7f3dbbea173d27750f57ce366c287a
--- /dev/null
+++ b/common/SmartFd.cpp
@@ -0,0 +1,111 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2015  CERN
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "common/exception/Exception.hpp"
+#include "common/SmartFd.hpp"
+
+#include <errno.h>
+#include <unistd.h>
+
+//-----------------------------------------------------------------------------
+// constructor
+//-----------------------------------------------------------------------------
+cta::SmartFd::SmartFd() throw():
+  m_fd(-1), m_closedCallback(NULL) {
+}
+
+//-----------------------------------------------------------------------------
+// constructor
+//-----------------------------------------------------------------------------
+cta::SmartFd::SmartFd(const int fd) throw():
+  m_fd(fd), m_closedCallback(NULL) {
+}
+
+//-----------------------------------------------------------------------------
+// setClosedCallback
+//-----------------------------------------------------------------------------
+void cta::SmartFd::setClosedCallback(ClosedCallback closedCallback)
+  throw() {
+  m_closedCallback = closedCallback;
+}
+
+//-----------------------------------------------------------------------------
+// reset
+//-----------------------------------------------------------------------------
+void cta::SmartFd::reset(const int fd = -1) throw() {
+  // If the new file descriptor is not the one already owned
+  if(fd != m_fd) {
+
+    // If this SmartFd still owns a file descriptor, then close it
+    if(m_fd >= 0) {
+      close(m_fd);
+      if(m_closedCallback) {
+        try {
+           (*m_closedCallback)(m_fd);
+        } catch(...) {
+           // Ignore any exception thrown my the m_closedCallback function
+           // because this reset function maybe called by the destructor of
+           // SmartFd
+        }
+      }
+    }
+
+    // Take ownership of the new file descriptor
+    m_fd = fd;
+  }
+}
+
+//-----------------------------------------------------------------------------
+// SmartFd assignment operator
+//-----------------------------------------------------------------------------
+cta::SmartFd &cta::SmartFd::operator=(SmartFd& obj) {
+  reset(obj.release());
+  return *this;
+}
+
+//-----------------------------------------------------------------------------
+// destructor
+//-----------------------------------------------------------------------------
+cta::SmartFd::~SmartFd() {
+  reset();
+}
+
+//-----------------------------------------------------------------------------
+// get
+//-----------------------------------------------------------------------------
+int cta::SmartFd::get() const throw() {
+  return m_fd;
+}
+
+//-----------------------------------------------------------------------------
+// release
+//-----------------------------------------------------------------------------
+int cta::SmartFd::release()  {
+  // If this SmartFd does not own a file descriptor
+  if(m_fd < 0) {
+    throw exception::Exception("Smart file-descriptor does not own a"
+      " file-descriptor");
+  }
+
+  const int tmpFd = m_fd;
+
+  // A negative number indicates this SmartFd does not own a file descriptor
+  m_fd = -1;
+
+  return tmpFd;
+}
diff --git a/common/SmartFd.hpp b/common/SmartFd.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ff67f4e406ff39e189977f6fecefff9aad959793
--- /dev/null
+++ b/common/SmartFd.hpp
@@ -0,0 +1,144 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2015  CERN
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+namespace cta {
+
+/**
+ * A smart file descriptor that owns a basic file descriptor.  When the smart
+ * file descriptor goes out of scope, it will close the file descriptor it
+ * owns.
+ */
+class SmartFd {
+public:
+
+  /**
+   * A pointer to a callback function that will called by the Smart
+   * immediately after the SmartFd has closed the file-descriptor it owns.
+   *
+   * Please note that any exception thrown by this function will be ignored
+   * because this function maybe called by the destructor of SmartFd.
+   *
+   * @param closedFd The value of the file descriptor that was closed.
+   */
+  typedef void (*ClosedCallback)(int closedFd);
+
+  /**
+   * Constructor.
+   *
+   */
+  SmartFd() throw();
+
+  /**
+   * Constructor.
+   *
+   * @param fd The file descriptor to be owned by the smart file
+   *           descriptor.
+   */
+  SmartFd(const int fd) throw();
+
+  /**
+   * Sets the function to be called back by the SmartFd immediately after
+   * the SmartFd has closed the file-descriptor it owns.
+   *
+   * Setting the callback function to NULL means that no function will be
+   * called.
+   *
+   * Please note any exception thrown by the callback function will be
+   * ignored because the callback function maybe called by the destructor of
+   * SmartFd.
+   *
+   * @param closedCallback This function will be called immediately after
+   *                       the SmartFd has closed the file-descriptor it owns.
+   *                       Please note that any exception thrown by this
+   *                       function will be ignored because this function
+   *                       maybe called by the destructor of SmartFd.
+   */
+  void setClosedCallback(ClosedCallback closedCallback) throw();
+
+  /**
+   * Take ownership of the specified file descriptor, closing the previously
+   * owned file descriptor if there is one and it is not the same as the one
+   * specified.
+   *
+   * @param fd The file descriptor to be owned, defaults to -1 if not
+   *           specified, where a negative number means this SmartFd does not
+   *           own a file descriptor.
+   */
+  void reset(const int fd) throw();
+
+  /**
+   * SmartFd assignment operator.
+   *
+   * This function does the following:
+   * <ul>
+   * <li> Calls release on the previous owner (obj);
+   * <li> Closes the file descriptor of this object if it already owns one.
+   * <li> Makes this object the owner of the file descriptor released from
+   *      the previous owner (obj).
+   * </ul>
+   */
+  SmartFd &operator=(SmartFd& obj) ;
+
+  /**
+   * Destructor.
+   *
+   * Closes the owned file descriptor if there is one.
+   */
+  ~SmartFd();
+
+  /**
+   * Returns the owned file descriptor or a negative number if this SmartFd
+   * does not own a file descriptor.
+   *
+   * @return The owned file desccriptor.
+   */
+  int get() const throw();
+
+  /**
+   * Releases the owned file descriptor.
+   *
+   * @return The released file descriptor.
+   */
+  int release() ;
+
+private:
+
+  /**
+   * The owned file descriptor.  A negative value means this SmartFd does not
+   * own a file descriptor..
+   */
+  int m_fd;
+
+  /**
+   * The function to be called immediately after the SmartFd has closed its
+   * file-descriptor.  A value of null means no function will be called.
+   */
+  ClosedCallback m_closedCallback;
+
+  /**
+   * Private copy-constructor to prevent users from trying to create a new
+   * copy of an object of this class.
+   * Not implemented so that it cannot be called
+   */
+  SmartFd(const SmartFd &obj) throw();
+
+}; // class SmartFd
+
+} // namespace cta
diff --git a/common/SmartFdTest.cpp b/common/SmartFdTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..08126870b8d52ad134f1ce43b6f94897124120bb
--- /dev/null
+++ b/common/SmartFdTest.cpp
@@ -0,0 +1,68 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2015  CERN
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "common/SmartFd.hpp"
+
+#include <gtest/gtest.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+namespace unitTests {
+
+class castor_utils_SmartFdTest : public ::testing::Test {
+protected:
+  static int s_fd;
+  static bool s_closedCallbackWasCalled;
+
+  virtual void SetUp() {
+    s_fd = -1;
+    s_closedCallbackWasCalled = false;
+  }
+
+  virtual void TearDown() {
+  }
+
+  static void closedCallback(int closedfd) {
+    s_fd = closedfd;
+    s_closedCallbackWasCalled = true;
+  }
+};
+
+int castor_utils_SmartFdTest::s_fd = -1;
+bool castor_utils_SmartFdTest::s_closedCallbackWasCalled = false;
+
+TEST_F(castor_utils_SmartFdTest, testClosedCallback) {
+  using namespace cta;
+
+  ASSERT_EQ(-1, s_fd);
+  ASSERT_EQ(false, s_closedCallbackWasCalled);
+
+  int fd = socket(PF_LOCAL, SOCK_STREAM, 0);
+  ASSERT_NE(-1, fd);
+
+  {
+    SmartFd sfd(fd);
+    sfd.setClosedCallback(closedCallback);
+  }
+  ASSERT_EQ(fd, s_fd);
+  ASSERT_EQ(true, s_closedCallbackWasCalled);
+}
+
+} // namespace unitTests