/** Entry point for Sashi-cli **/ #include "pchheader.hpp" #include "cli-manager.hpp" #define PARSE_ERROR \ { \ std::cerr << "Arguments mismatch.\n"; \ std::cerr << "Usage:\n"; \ std::cerr << "sashi status\n"; \ std::cerr << "sashi json \n"; \ std::cerr << "Example: sashi json '{\"container_name\":\"\", ...}'\n"; \ return -1; \ } /** * Performs any cleanup on graceful application termination. */ void deinit() { cli::deinit(); } void segfault_handler(int signum) { std::cout << boost::stacktrace::stacktrace() << std::endl; exit(SIGABRT); } /** * Global exception handler for std exceptions. */ void std_terminate() noexcept { const std::exception_ptr exptr = std::current_exception(); if (exptr != 0) { try { std::rethrow_exception(exptr); } catch (std::exception &ex) { std::cerr << "std error: " << ex.what() << std::endl; } catch (...) { std::cerr << "std error: Terminated due to unknown exception\n"; } } else { std::cerr << "std error: Terminated due to unknown reason\n"; } std::cerr << boost::stacktrace::stacktrace() << std::endl; exit(1); } int main(int argc, char **argv) { // Register exception and segfault handlers. std::set_terminate(&std_terminate); signal(SIGSEGV, &segfault_handler); signal(SIGABRT, &segfault_handler); // Disable SIGPIPE to avoid crashing on broken pipe IO. { sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGPIPE); // sigprocmask is used instead of pthread_sigmask since this is single threaded. sigprocmask(SIG_BLOCK, &mask, NULL); } if (argc > 1) { // Take the realpath of sash exec path. std::array buffer; ::realpath(argv[0], buffer.data()); buffer[PATH_MAX] = '\0'; const std::string exec_dir = dirname(buffer.data()); const std::string command = argv[1]; if (command == "status") { if (cli::init(exec_dir) == -1) return -1; std::cout << cli::ctx.socket_path << std::endl; cli::deinit(); return 0; } else if (command == "json" && argc == 3) { std::string output; if (cli::init(exec_dir) == -1 || cli::write_to_socket(argv[2]) == -1 || cli::read_from_socket(output) == -1) { cli::deinit(); return -1; } std::cout << output << std::endl; cli::deinit(); return 0; } } PARSE_ERROR }