[CAPI] Add permission denied return
authorJihoon Lee <jhoon.it.lee@samsung.com>
Tue, 24 Aug 2021 10:47:37 +0000 (19:47 +0900)
committerJijoong Moon <jijoong.moon@samsung.com>
Fri, 27 Aug 2021 09:20:23 +0000 (18:20 +0900)
This patch add permission denied return when failed to read/write to a
file.

**Self evaluation:**
1. Build test: [X]Passed [ ]Failed [ ]Skipped
2. Run test: [X]Passed [ ]Failed [ ]Skipped

Signed-off-by: Jihoon Lee <jhoon.it.lee@samsung.com>
Applications/TransferLearning/Draw_Classification/res/Training.ini
api/capi/src/nntrainer.cpp
nntrainer/layers/layer_node.cpp
nntrainer/models/neuralnet.cpp
nntrainer/nntrainer_error.h
nntrainer/utils/parse_util.h
nntrainer/utils/util_func.h

index 7364017b983894f165ac2b2010b46f049af03530..2732d7792e7aee8f2591714bb128a641d8d36b31 100644 (file)
@@ -5,7 +5,7 @@ Type = NeuralNetwork    # Network Type : Regression, KNN, NeuralNetwork
 Epochs = 10            # Epochs
 Loss = cross                   # Loss function : mse (mean squared error)
                         #                       cross (cross entropy)
-Save_Path = "model_draw_cls.bin"       # model path to save / read
+Save_Path = model_draw_cls.bin         # model path to save / read
 batch_size = 1         # batch size
 
 [Optimizer]
index 0f6f66cdc60a6294c1cd744f5731320b60171099..51afc50a91896b76fe610711cb4e70cc9307dc5a 100644 (file)
@@ -66,6 +66,9 @@ template <typename F> static int nntrainer_exception_boundary(F &&func) {
   } catch (nntrainer::exception::not_supported &e) {
     ml_loge("%s %s", typeid(e).name(), e.what());
     return ML_ERROR_INVALID_PARAMETER;
+  } catch (nntrainer::exception::permission_denied &e) {
+    ml_loge("%s %s", typeid(e).name(), e.what());
+    return ML_ERROR_PERMISSION_DENIED;
   } catch (std::invalid_argument &e) {
     ml_loge("%s %s", typeid(e).name(), e.what());
     return ML_ERROR_INVALID_PARAMETER;
index 3f5ba861ff5cbf2b94725113503b7d723279abce..b173df0d0f8f73fd003743603d1931dd2dc54445 100644 (file)
@@ -20,6 +20,7 @@
 #include <node_exporter.h>
 #include <parse_util.h>
 #include <time_dist.h>
+#include <util_func.h>
 
 #include <base_properties.h>
 #include <common_properties.h>
index 9d6412c906e23241e81e7eea967034f5c4dce432..141e8482a8a508618036610b8397ecb604a44c93 100644 (file)
@@ -362,11 +362,8 @@ void NeuralNetwork::save(const std::string &file_path,
   /// not delegating for now as required logics are managable for now.
   switch (format) {
   case ml::train::ModelFormat::MODEL_FORMAT_BIN: {
-    std::ofstream model_file(file_path, std::ios::out | std::ios::binary);
-    /// @todo, if errno == EACCESS or EPERM, throw PERMISSION DENIED error
-    NNTR_THROW_IF(!model_file.good(), std::invalid_argument)
-      << "model file not opened, file path: " << file_path
-      << " reason: " << strerror(errno);
+    auto model_file = checkedOpenStream<std::ofstream>(
+      file_path, std::ios::out | std::ios::binary);
     for (auto iter = model_graph.cbegin(); iter != model_graph.cend(); iter++) {
       (*iter)->save(model_file);
     }
@@ -393,12 +390,9 @@ void NeuralNetwork::load(const std::string &file_path,
       << "Cannot load if not initialized yet, path: " << file_path
       << " format: " << static_cast<unsigned>(format);
 
-    std::ifstream model_file(file_path, std::ios::in | std::ios::binary);
-    /// @todo, if errno == EACCESS or EPERM, throw PERMISSION DENIED error
-    NNTR_THROW_IF(!model_file.good(), std::invalid_argument)
-      << "model file not opened, file path: " << file_path
-      << " reason: " << strerror(errno);
-
+    auto model_file = checkedOpenStream<std::ifstream>(
+      file_path, std::ios::in | std::ios::binary);
+    std::cerr << file_path << '\n';
     for (auto iter = model_graph.cbegin(); iter != model_graph.cend(); iter++) {
       (*iter)->read(model_file);
     }
@@ -421,7 +415,8 @@ void NeuralNetwork::load(const std::string &file_path,
     int ret = loadFromConfig(file_path);
     throw_status(ret);
     if (!save_path.empty()) {
-      /// @todo checkedOpenhere
+      checkedOpenStream<std::ifstream>(save_path,
+                                       std::ios::in | std::ios::binary);
       load_path = save_path;
     }
     break;
index f6b3eb039ed5168cf279f832b92b7963cdb3f392..77b1b811d16984b067e8bb3a00db88fddec70a5f 100644 (file)
@@ -57,8 +57,13 @@ public:
    * @brief Construct a new Error Notification object
    *
    */
-  explicit ErrorNotification() : cleanup_func([] {}) {}
+  explicit ErrorNotification() : cleanup_func() {}
 
+  /**
+   * @brief Construct a new Error Notification object
+   *
+   * @param cleanup_func_ clean up function
+   */
   explicit ErrorNotification(std::function<void()> cleanup_func_) :
     cleanup_func(cleanup_func_) {}
 
@@ -68,14 +73,24 @@ public:
    *
    */
   ~ErrorNotification() noexcept(false) {
-    cleanup_func();
+    if (cleanup_func) {
+      cleanup_func();
+    }
     throw Err(ss.str().c_str());
   }
 
+  /**
+   * @brief Error notification stream wrapper
+   *
+   * @tparam T anything that will be delegated to the move
+   * @param out out stream
+   * @param e anything to pass to the stream
+   * @return ErrorNotification<Err>&& self
+   */
   template <typename T>
   friend ErrorNotification<Err> &&operator<<(ErrorNotification<Err> &&out,
                                              T &&e) {
-    out.ss << e;
+    out.ss << std::forward<T>(e);
     return std::move(out);
   }
 
@@ -93,6 +108,13 @@ struct not_supported : public std::invalid_argument {
   using invalid_argument::invalid_argument;
 };
 
+/**
+ * @brief derived class of invalid argument to represent permission is denied
+ */
+struct permission_denied : public std::invalid_argument {
+  using invalid_argument::invalid_argument;
+};
+
 } // namespace exception
 
 } // namespace nntrainer
index b03f25466239b1c5a5f2a5eb2e48227dc5e79367..bc5f20274c5f416ff735d69f314f151912a57072 100644 (file)
@@ -30,6 +30,7 @@
 #include <vector>
 
 #include <ml-api-common.h>
+#include <nntrainer_error.h>
 #include <props_util.h>
 
 namespace nntrainer {
@@ -125,16 +126,6 @@ unsigned int parseNetProperty(std::string property);
  */
 unsigned int parseDataProperty(std::string property);
 
-/**
- * @brief     print instance info. as <Type at (address)>
- * @param[in] std::ostream &out, T&& t
- * @param[in] t pointer to the instance
- */
-template <typename T,
-          typename std::enable_if_t<std::is_pointer<T>::value, T> * = nullptr>
-void printInstance(std::ostream &out, const T &t) {
-  out << '<' << typeid(*t).name() << " at " << t << '>' << std::endl;
-}
 } /* namespace nntrainer */
 
 #endif /* __cplusplus */
index c5600e27b23c9f316ea93cc401c091a37edd4fa6..411c02a410caa4202120d2d03c332674aed1d704 100644 (file)
 #define __UTIL_FUNC_H__
 #ifdef __cplusplus
 
-#include <tensor.h>
+#include <cstring>
+#include <sstream>
 
+#include <nntrainer_error.h>
+#include <tensor.h>
 namespace nntrainer {
 
 /**
@@ -153,6 +156,43 @@ void writeString(std::ofstream &file, const std::string &str,
  */
 bool endswith(const std::string &target, const std::string &suffix);
 
+/**
+ * @brief     print instance info. as <Type at (address)>
+ * @param[in] std::ostream &out, T&& t
+ * @param[in] t pointer to the instance
+ */
+template <typename T,
+          typename std::enable_if_t<std::is_pointer<T>::value, T> * = nullptr>
+void printInstance(std::ostream &out, const T &t) {
+  out << '<' << typeid(*t).name() << " at " << t << '>' << std::endl;
+}
+
+/**
+ * @brief creat a stream, and if !stream.good() throw appropriate error code
+ * depending on @c errno
+ *
+ * @tparam T return type
+ * @param path path
+ * @param mode mode to open path
+ * @return T created stream
+ */
+template <typename T>
+T checkedOpenStream(const std::string &path, std::ios_base::openmode mode) {
+  T model_file(path, mode);
+  if (!model_file.good()) {
+    std::stringstream ss;
+    ss << "[parseutil] requested file not opened, file path: " << path
+       << " reason: " << std::strerror(errno);
+    if (errno == EPERM || errno == EACCES) {
+      throw nntrainer::exception::permission_denied(ss.str().c_str());
+    } else {
+      throw std::invalid_argument(ss.str().c_str());
+    }
+  }
+
+  return model_file;
+}
+
 } /* namespace nntrainer */
 
 #endif /* __cplusplus */