Switch to std::filesystem

Change-Id: I3b8e8adfae9b063f97396d35a5f2296df56a3eb9
diff --git a/daemon/face/unix-stream-channel.cpp b/daemon/face/unix-stream-channel.cpp
index 2b09ed4..a3299f6 100644
--- a/daemon/face/unix-stream-channel.cpp
+++ b/daemon/face/unix-stream-channel.cpp
@@ -29,9 +29,8 @@
 #include "unix-stream-transport.hpp"
 #include "common/global.hpp"
 
-#include <boost/filesystem/exception.hpp>
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
+#include <filesystem>
+#include <system_error>
 
 namespace nfd::face {
 
@@ -51,10 +50,11 @@
 {
   if (isListening()) {
     // use the non-throwing variants during destruction and ignore any errors
-    boost::system::error_code ec;
-    m_acceptor.close(ec);
+    boost::system::error_code ec1;
+    m_acceptor.close(ec1);
     NFD_LOG_CHAN_TRACE("Removing socket file");
-    boost::filesystem::remove(m_endpoint.path(), ec);
+    std::error_code ec2;
+    std::filesystem::remove(m_endpoint.path(), ec2);
   }
 }
 
@@ -68,7 +68,7 @@
     return;
   }
 
-  namespace fs = boost::filesystem;
+  namespace fs = std::filesystem;
 
   fs::path socketPath = m_endpoint.path();
   // ensure parent directory exists
@@ -77,18 +77,18 @@
     NFD_LOG_CHAN_TRACE("Created directory " << parent);
   }
 
-  boost::system::error_code ec;
-  fs::file_type type = fs::symlink_status(socketPath).type();
-  if (type == fs::socket_file) {
+  auto type = fs::symlink_status(socketPath).type();
+  if (type == fs::file_type::socket) {
     // if the socket file already exists, there may be another instance
     // of NFD running on the system: make sure we don't steal its socket
+    boost::system::error_code ec;
     boost::asio::local::stream_protocol::socket socket(getGlobalIoService());
     socket.connect(m_endpoint, ec);
     NFD_LOG_CHAN_TRACE("connect() on existing socket file returned: " << ec.message());
     if (!ec) {
       // someone answered, leave the socket alone
-      ec = boost::system::errc::make_error_code(boost::system::errc::address_in_use);
-      NDN_THROW_NO_STACK(fs::filesystem_error("UnixStreamChannel::listen", socketPath, ec));
+      NDN_THROW_NO_STACK(fs::filesystem_error("UnixStreamChannel::listen", socketPath,
+                                              std::make_error_code(std::errc::address_in_use)));
     }
     else if (ec == boost::asio::error::connection_refused ||
              ec == boost::asio::error::timed_out) {
@@ -97,11 +97,11 @@
       fs::remove(socketPath);
     }
   }
-  else if (type != fs::file_not_found) {
+  else if (type != fs::file_type::not_found) {
     // the file exists but is not a socket: this is a fatal error as we cannot
     // safely overwrite the file without potentially risking data loss
-    ec = boost::system::errc::make_error_code(boost::system::errc::not_a_socket);
-    NDN_THROW_NO_STACK(fs::filesystem_error("UnixStreamChannel::listen", socketPath, ec));
+    NDN_THROW_NO_STACK(fs::filesystem_error("UnixStreamChannel::listen", socketPath,
+                                            std::make_error_code(std::errc::not_a_socket)));
   }
 
   try {
@@ -119,8 +119,8 @@
   // the destructor will still remove the socket file
   m_isListening = true;
 
-  fs::permissions(socketPath, fs::owner_read | fs::group_read | fs::others_read |
-                              fs::owner_write | fs::group_write | fs::others_write);
+  fs::permissions(socketPath, fs::perms::owner_read | fs::perms::group_read | fs::perms::others_read |
+                              fs::perms::owner_write | fs::perms::group_write | fs::perms::others_write);
 
   accept(onFaceCreated, onAcceptFailed);
   NFD_LOG_CHAN_DEBUG("Started listening");
diff --git a/daemon/face/unix-stream-channel.hpp b/daemon/face/unix-stream-channel.hpp
index dbe53d4..d99ea33 100644
--- a/daemon/face/unix-stream-channel.hpp
+++ b/daemon/face/unix-stream-channel.hpp
@@ -80,7 +80,7 @@
    *                       returns an error)
    * \param backlog        The maximum length of the queue of pending incoming
    *                       connections
-   * \throw boost::system::system_error
+   * \throw std::system_error
    */
   void
   listen(const FaceCreatedCallback& onFaceCreated,
diff --git a/daemon/face/unix-stream-factory.cpp b/daemon/face/unix-stream-factory.cpp
index a1cc2fe..e20a8dd 100644
--- a/daemon/face/unix-stream-factory.cpp
+++ b/daemon/face/unix-stream-factory.cpp
@@ -25,7 +25,7 @@
 
 #include "unix-stream-factory.hpp"
 
-#include <boost/filesystem/operations.hpp>
+#include <filesystem>
 
 namespace nfd::face {
 
@@ -86,8 +86,8 @@
 shared_ptr<UnixStreamChannel>
 UnixStreamFactory::createChannel(const std::string& socketPath)
 {
-  auto normalizedPath = boost::filesystem::weakly_canonical(boost::filesystem::absolute(socketPath));
-  unix_stream::Endpoint endpoint(normalizedPath.string());
+  auto normalizedPath = std::filesystem::weakly_canonical(std::filesystem::absolute(socketPath));
+  unix_stream::Endpoint endpoint(normalizedPath);
 
   auto it = m_channels.find(endpoint);
   if (it != m_channels.end())
diff --git a/daemon/main.cpp b/daemon/main.cpp
index cc3c58a..60edb1e 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -45,6 +45,7 @@
 #include <atomic>
 #include <condition_variable>
 #include <iostream>
+#include <system_error>
 #include <thread>
 
 #include <ndn-cxx/util/logging.hpp>
@@ -331,6 +332,14 @@
     }
     return 1;
   }
+  catch (const std::system_error& e) {
+    NFD_LOG_FATAL(boost::diagnostic_information(e));
+    if (e.code() == std::errc::operation_not_permitted ||
+        e.code() == std::errc::permission_denied) {
+      return 4;
+    }
+    return 1;
+  }
   catch (const std::exception& e) {
     NFD_LOG_FATAL(boost::diagnostic_information(e));
     return 1;
diff --git a/daemon/mgmt/command-authenticator.cpp b/daemon/mgmt/command-authenticator.cpp
index 1f1b036..b07d23d 100644
--- a/daemon/mgmt/command-authenticator.cpp
+++ b/daemon/mgmt/command-authenticator.cpp
@@ -34,8 +34,7 @@
 #include <ndn-cxx/tag.hpp>
 #include <ndn-cxx/util/io.hpp>
 
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
+#include <filesystem>
 
 namespace security = ndn::security;
 
@@ -158,12 +157,12 @@
                    "SHOULD NOT be used in production environments");
     }
     else {
-      using namespace boost::filesystem;
-      path certfilePath = absolute(certfile, path(filename).parent_path());
-      cert = ndn::io::load<security::Certificate>(certfilePath.string());
+      auto certfilePath = std::filesystem::absolute(filename).parent_path() / certfile;
+      certfilePath = certfilePath.lexically_normal();
+      cert = ndn::io::load<security::Certificate>(certfilePath);
       if (cert == nullptr) {
-        NDN_THROW(ConfigFile::Error("cannot load certfile " + certfilePath.string() +
-                                    " for authorize[" + std::to_string(authSectionIndex) + "]"));
+        NDN_THROW(ConfigFile::Error("cannot load certfile '" + certfilePath.native() +
+                                    "' for authorize[" + std::to_string(authSectionIndex) + "]"));
       }
     }