diff --git a/src/xir/attrs/attr_def.cpp b/src/xir/attrs/attr_def.cpp index a7c2cc8..301aec3 100644 --- a/src/xir/attrs/attr_def.cpp +++ b/src/xir/attrs/attr_def.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include #include diff --git a/src/xir/graph/graph_imp.cpp b/src/xir/graph/graph_imp.cpp index 0613000..657819f 100644 --- a/src/xir/graph/graph_imp.cpp +++ b/src/xir/graph/graph_imp.cpp @@ -17,6 +17,16 @@ #include "xir/graph/graph_imp.hpp" +#include +#include +#include +#ifdef _WIN32 +# include +#else +# include +# include +#endif + #include "UniLog/UniLog.hpp" #include "xir/graph/serialize_v2.hpp" #include "xir/op/op_def.hpp" @@ -25,6 +35,39 @@ namespace xir { +namespace { + +int run_dot_no_shell(const std::string& format, const std::string& input_dot, + const std::string& output_file) { + const auto fmt = std::string{"-T"} + format; +#ifdef _WIN32 + const char* argv[] = {"dot", fmt.c_str(), input_dot.c_str(), "-o", + output_file.c_str(), nullptr}; + return _spawnvp(_P_WAIT, "dot", argv); +#else + auto pid = fork(); + if (pid < 0) { + return -1; + } + if (pid == 0) { + const char* argv[] = {"dot", fmt.c_str(), input_dot.c_str(), "-o", + output_file.c_str(), nullptr}; + execvp("dot", const_cast(argv)); + _exit(127); + } + int status = 0; + if (waitpid(pid, &status, 0) < 0) { + return -1; + } + if (WIFEXITED(status)) { + return WEXITSTATUS(status); + } + return -1; +#endif +} + +} // namespace + GraphImp::GraphImp(std::string name) : graph_{std::make_unique(0)}, root_subgraph_{ @@ -248,20 +291,14 @@ void GraphImp::visualize(const std::string& file_path, const std::string& format) const { auto file_name_dot = file_path + ".dot"; save_to_dot(file_name_dot); - auto create_fig_from_dot = - "dot -T" + format + " " + file_name_dot + " -o " + file_path; - auto result = std::system(create_fig_from_dot.c_str()); + auto result = run_dot_no_shell(format, file_name_dot, file_path); UNI_LOG_CHECK(result == 0, XIR_OPERATION_FAILED) - << "command: \"" << create_fig_from_dot << "\", std::system exit(" - << result << ")"; -#ifdef _WIN32 - auto rm_dot = "del " + file_name_dot; -#else - auto rm_dot = "rm " + file_name_dot; -#endif - result = std::system(rm_dot.c_str()); + << "failed to run dot for output file \"" << file_path + << "\", exit code: " << result; + result = std::remove(file_name_dot.c_str()); UNI_LOG_CHECK(result == 0, XIR_OPERATION_FAILED) - << "command: \"" << rm_dot << "\", std::system exit(" << result << ")"; + << "failed to remove temporary file \"" << file_name_dot + << "\", errno: " << errno; } std::int64_t GraphImp::compute_model_size() const { diff --git a/src/xir/graph/serialize_v2.hpp b/src/xir/graph/serialize_v2.hpp index fc49cad..3feff8a 100644 --- a/src/xir/graph/serialize_v2.hpp +++ b/src/xir/graph/serialize_v2.hpp @@ -17,6 +17,7 @@ #pragma once +#include #include #include #include