Add signal handling, improve robustness for sequence number file writes.

Also removes now unused Fib::Clean method.

Change-Id: I7db2d66fa329920467ea7d5e7c16ff5a2ee9f44b
diff --git a/src/main.cpp b/src/main.cpp
index dfe54a7..ca0e8ec 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2023,  The University of Memphis,
+ * Copyright (c) 2014-2025,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -88,7 +88,6 @@
     face.processEvents();
   }
   catch (const std::exception& e) {
-    nlsr.getFib().clean();
     std::cerr << "FATAL: " << boost::diagnostic_information(e) << std::endl;
     return 1;
   }
diff --git a/src/nlsr.cpp b/src/nlsr.cpp
index 144f1d3..4d52fa0 100644
--- a/src/nlsr.cpp
+++ b/src/nlsr.cpp
@@ -78,6 +78,7 @@
       m_lsdb)
   , m_statsCollector(m_lsdb, m_helloProtocol)
   , m_faceMonitor(m_face)
+  , m_terminateSignals(face.getIoContext(), SIGINT, SIGTERM)
 {
   NLSR_LOG_DEBUG("Initializing Nlsr");
 
@@ -107,6 +108,10 @@
       neighbor.setLinkCost(0);
     }
   }
+
+  m_terminateSignals.async_wait([this] (auto&&... args) {
+    terminate(std::forward<decltype(args)>(args)...);
+  });
 }
 
 void
@@ -365,4 +370,13 @@
     });
 }
 
+void
+Nlsr::terminate(const boost::system::error_code& error, int signalNo)
+{
+  if (error)
+    return;
+  NLSR_LOG_INFO("Caught signal " << signalNo << " (" << ::strsignal(signalNo) << "), exiting...");
+  m_face.getIoContext().stop();
+}
+
 } // namespace nlsr
diff --git a/src/nlsr.hpp b/src/nlsr.hpp
index f375eca..891eda9 100644
--- a/src/nlsr.hpp
+++ b/src/nlsr.hpp
@@ -48,6 +48,7 @@
 #include <ndn-cxx/security/key-chain.hpp>
 #include <ndn-cxx/util/scheduler.hpp>
 
+#include <boost/asio/signal_set.hpp>
 namespace nlsr {
 
 class Nlsr
@@ -157,6 +158,9 @@
   void
   enableIncomingFaceIdIndication();
 
+  void
+  terminate(const boost::system::error_code& error, int signalNo);
+
 public:
   static inline const ndn::Name LOCALHOST_PREFIX{"/localhost/nlsr"};
 
@@ -196,6 +200,7 @@
 
 private:
   ndn::nfd::FaceMonitor m_faceMonitor;
+  boost::asio::signal_set m_terminateSignals;
 };
 
 } // namespace nlsr
diff --git a/src/route/fib.cpp b/src/route/fib.cpp
index 7f3f076..76affde 100644
--- a/src/route/fib.cpp
+++ b/src/route/fib.cpp
@@ -153,17 +153,6 @@
   }
 }
 
-void
-Fib::clean()
-{
-  NLSR_LOG_DEBUG("Clean called");
-  for (const auto& it : m_table) {
-    for (const auto& hop : it.second.nexthopSet) {
-      unregisterPrefix(it.second.name, hop.getConnectingFaceUri());
-    }
-  }
-}
-
 unsigned int
 Fib::getNumberOfFacesForName(const NexthopList& nextHopList)
 {
diff --git a/src/route/fib.hpp b/src/route/fib.hpp
index 8c53125..7be0001 100644
--- a/src/route/fib.hpp
+++ b/src/route/fib.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2023,  The University of Memphis,
+ * Copyright (c) 2014-2025,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -90,17 +90,6 @@
   void
   update(const ndn::Name& name, const NexthopList& allHops);
 
-  /*! \brief Remove all entries from the FIB.
-   *
-   * This method is called before terminating NLSR to minimize the
-   * time NFD spends routing on now-invalid information. This is not
-   * strictly necessary, because eventually those prefix registrations
-   * will expire, but cleaning up after ourselves improves
-   * performance.
-   */
-  void
-  clean();
-
   void
   setEntryRefreshTime(int32_t fert)
   {
diff --git a/src/sequencing-manager.cpp b/src/sequencing-manager.cpp
index ae0c8b5..6046b10 100644
--- a/src/sequencing-manager.cpp
+++ b/src/sequencing-manager.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2020,  The University of Memphis,
+/*
+ * Copyright (c) 2014-2025,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -17,7 +17,7 @@
  *
  * You should have received a copy of the GNU General Public License along with
  * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
 
 #include "sequencing-manager.hpp"
 #include "logger.hpp"
@@ -43,13 +43,13 @@
 SequencingManager::writeSeqNoToFile() const
 {
   writeLog();
-  std::ofstream outputFile(m_seqFileNameWithPath.c_str());
-  std::ostringstream os;
-  os << "NameLsaSeq " << std::to_string(m_nameLsaSeq) << "\n"
-     << "AdjLsaSeq "  << std::to_string(m_adjLsaSeq)  << "\n"
-     << "CorLsaSeq "  << std::to_string(m_corLsaSeq);
-  outputFile << os.str();
+  std::string tempPath = m_seqFileNameWithPath + ".tmp";
+  std::ofstream outputFile(tempPath.c_str());
+  outputFile << "NameLsaSeq " << m_nameLsaSeq << "\n"
+             << "AdjLsaSeq "  << m_adjLsaSeq  << "\n"
+             << "CorLsaSeq "  << m_corLsaSeq;
   outputFile.close();
+  std::filesystem::rename(tempPath, m_seqFileNameWithPath);
 }
 
 void