diff --git a/src/conf.cpp b/src/conf.cpp index 4d910883..49b71cad 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -16,6 +16,8 @@ namespace conf // Stores the initial startup mode of the node. ROLE startup_mode; + constexpr int FILE_PERMS = 0644; + constexpr const char *ROLE_OBSERVER = "observer"; constexpr const char *ROLE_VALIDATOR = "validator"; constexpr const char *PUBLIC = "public"; @@ -208,19 +210,24 @@ namespace conf int read_config(contract_config &cfg) { // Read the config file into json document object. + std::string buf; + if (util::read_from_fd(ctx.config_fd, buf) == -1) + { + std::cerr << "Error reading from the config file. " << errno << '\n'; + return -1; + } - std::ifstream ifs(ctx.config_file); jsoncons::ojson d; try { - d = jsoncons::ojson::parse(ifs, jsoncons::strict_json_parsing()); + d = jsoncons::ojson::parse(buf, jsoncons::strict_json_parsing()); } catch (const std::exception &e) { std::cerr << "Invalid config file format. " << e.what() << '\n'; return -1; } - ifs.close(); + buf.clear(); try { @@ -658,20 +665,34 @@ namespace conf if (!util::is_file_exists(path)) return 0; + const int fd = open(path.data(), O_RDONLY); + if (fd == -1) + { + std::cerr << "Error opening the patch config file. " << errno << '\n'; + return -1; + } + // If patch file exist, read the patch file values to a json doc and then persist the values into hp.cfg. - std::ifstream ifs(path); + std::string buf; + if (util::read_from_fd(fd, buf) == -1) + { + std::cerr << "Error reading from the patch config file. " << errno << '\n'; + close(fd); + return -1; + } + close(fd); + jsoncons::ojson jdoc; try { - jdoc = jsoncons::ojson::parse(ifs, jsoncons::strict_json_parsing()); + jdoc = jsoncons::ojson::parse(buf, jsoncons::strict_json_parsing()); } catch (const std::exception &e) { - ifs.close(); std::cerr << "Invalid patch config file format. " << e.what() << '\n'; return -1; } - ifs.close(); + buf.clear(); // Persist new changes to HP config file. if (parse_contract_section_json(cfg.contract, jdoc, false) == -1 || @@ -869,20 +890,33 @@ namespace conf */ int write_json_file(const std::string &file_path, const jsoncons::ojson &d) { - std::ofstream ofs(file_path); + std::string json; + // Convert json object to a string. try { jsoncons::json_options options; options.object_array_line_splits(jsoncons::line_split_kind::multi_line); - ofs << jsoncons::pretty_print(d, options); + std::ostringstream os; + os << jsoncons::pretty_print(d, options); + json = os.str(); + os.clear(); } catch (const std::exception &e) { - std::cerr << "Writing file failed. " << ctx.config_file << std::endl; - ofs.close(); + std::cerr << "Converting json to string failed. " << file_path << std::endl; return -1; } - ofs.close(); + + // O_TRUNC flag is used to trucate existing content from the file. + const int fd = open(file_path.data(), O_CREAT | O_RDWR | O_TRUNC, FILE_PERMS); + if (fd == -1 || write(fd, json.data(), json.size()) == -1) + { + std::cerr << "Writing file failed. " << file_path << std::endl; + if (fd != -1) + close(fd); + return -1; + } + close(fd); return 0; } diff --git a/src/pchheader.hpp b/src/pchheader.hpp index 9d2ba4f5..ca58f163 100644 --- a/src/pchheader.hpp +++ b/src/pchheader.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/src/util/util.cpp b/src/util/util.cpp index 6cb7644f..811d38c9 100644 --- a/src/util/util.cpp +++ b/src/util/util.cpp @@ -364,6 +364,23 @@ namespace util return name; } + /** + * Reads from a given file discriptor. + * @param fd File descriptor to be read. + * @param buf String buffer to be populated. + * @return Returns number of bytes read in a successful read and -1 on error. + */ + int read_from_fd(const int fd, std::string &buf) + { + struct stat st; + if (fstat(fd, &st) == -1) + return -1; + + buf.resize(st.st_size); + + return read(fd, buf.data(), buf.size()); + } + /** * Create a record lock for the file descriptor. Lock is associated with the process (Not for forked child processes). * @param fd File descriptor to be locked. diff --git a/src/util/util.hpp b/src/util/util.hpp index 40d82a6a..0bfaffbc 100644 --- a/src/util/util.hpp +++ b/src/util/util.hpp @@ -80,6 +80,8 @@ namespace util const std::string get_name(std::string_view path); + int read_from_fd(const int fd, std::string &buf); + int set_lock(const int fd, struct flock &lock, const bool is_rwlock, const off_t start, const off_t len); int release_lock(const int fd, struct flock &lock);