// Copyright (c) 2006, 2007 Julio M. Merino Vidal // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling // Copyright (c) 2009 Boris Schaeling // Copyright (c) 2010 Felipe Tanus, Boris Schaeling // Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #define BOOST_USE_WINDOWS_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(BOOST_POSIX_API) # include # include # include # include #elif defined(BOOST_WINDOWS_API) # include #endif using namespace boost::program_options; int main(int argc, char *argv[]) { options_description desc; desc.add_options() ("echo-stdout", value()) ("echo-stderr", value()) ("echo-stdout-stderr", value()) ("echo-argv", bool_switch()) ("exit-code", value()) ("wait", value()) ("is-closed-stdin", bool_switch()) ("is-closed-stdout", bool_switch()) ("is-closed-stderr", bool_switch()) ("is-nul-stdin", bool_switch()) ("is-nul-stdout", bool_switch()) ("is-nul-stderr", bool_switch()) ("loop", bool_switch()) ("abort", bool_switch()) ("prefix", value()) ("prefix-once", value()) ("pwd", bool_switch()) ("query", value()) ("stdin-to-stdout", bool_switch()) ("has-handle", value()) #if defined(BOOST_POSIX_API) ("posix-echo-one", value >()->multitoken()) ("posix-echo-two", value >()->multitoken()); #elif defined(BOOST_WINDOWS_API) ("windows-print-showwindow", bool_switch()) ("windows-print-flags", bool_switch()); #endif variables_map vm; command_line_parser parser(argc, argv); store(parser.options(desc).allow_unregistered().run(), vm); notify(vm); if (vm.count("echo-stdout")) { std::cout << vm["echo-stdout"].as() << std::endl; } else if (vm.count("echo-stderr")) { std::cerr << vm["echo-stderr"].as() << std::endl; } else if (vm.count("echo-stdout-stderr")) { std::cout << vm["echo-stdout-stderr"].as() << std::endl; std::cerr << vm["echo-stdout-stderr"].as() << std::endl; } else if (vm["echo-argv"].as()) { std::vector args(argv+1, argv + argc); for (auto & arg : args) std::cout << arg << std::endl; } else if (vm.count("exit-code")) { return vm["exit-code"].as(); } else if (vm.count("wait")) { int sec = vm["wait"].as(); #if defined(BOOST_POSIX_API) sleep(sec); #elif defined(BOOST_WINDOWS_API) Sleep(sec * 1000); #endif } else if (vm["is-closed-stdin"].as()) { std::string s; std::cin >> s; return std::cin.eof() ? EXIT_SUCCESS : EXIT_FAILURE; } else if (vm["is-closed-stdout"].as()) { std::cout << "foo" << std::endl; return std::cout.bad() ? EXIT_SUCCESS : EXIT_FAILURE; } else if (vm["is-closed-stderr"].as()) { std::cerr << "foo" << std::endl; return std::cerr.bad() ? EXIT_SUCCESS : EXIT_FAILURE; } else if (vm["is-nul-stdin"].as()) { #if defined(BOOST_POSIX_API) char buffer[1]; int res = read(STDIN_FILENO, buffer, 1); return res != -1 ? EXIT_SUCCESS : EXIT_FAILURE; #elif defined(BOOST_WINDOWS_API) HANDLE h = GetStdHandle(STD_INPUT_HANDLE); if (h == INVALID_HANDLE_VALUE) return EXIT_FAILURE; char buffer[1]; DWORD read; BOOL res = ReadFile(h, buffer, 1, &read, NULL); CloseHandle(h); return res ? EXIT_SUCCESS : EXIT_FAILURE; #endif } else if (vm["is-nul-stdout"].as()) { std::cout << "foo" << std::endl; return std::cout.bad() ? EXIT_FAILURE : EXIT_SUCCESS; } else if (vm["is-nul-stderr"].as()) { std::cerr << "foo" << std::endl; return std::cerr.bad() ? EXIT_FAILURE : EXIT_SUCCESS; } else if (vm["loop"].as()) { while (true); } else if (vm["abort"].as()) { std::abort(); } else if (vm.count("prefix")) { std::string line; while (std::getline(std::cin, line)) std::cout << vm["prefix"].as() << line << std::endl; } else if (vm.count("prefix-once")) { std::string line; std::getline(std::cin, line); std::cout << vm["prefix-once"].as() << line << std::endl; } else if (vm["pwd"].as()) { std::cout << boost::filesystem::current_path().string() << std::endl; } else if (vm.count("query")) { auto key = vm["query"].as(); auto env = boost::this_process::environment(); auto val = env[key]; if (val.empty()) std::cout << "************** empty environment **************" << std::endl; else std::cout << val.to_string() << std::endl; } else if (vm["stdin-to-stdout"].as()) { char ch; while (std::cin >> std::noskipws >> ch) std::cout << ch << std::flush; } #if defined(BOOST_POSIX_API) else if (vm.count("posix-echo-one")) { using namespace boost::iostreams; std::vector v = vm["posix-echo-one"].as >(); int fd = boost::lexical_cast(v[0]); file_descriptor_sink sink(fd, close_handle); stream os(sink); os << v[1] << std::endl; } else if (vm.count("posix-echo-two")) { using namespace boost::iostreams; std::vector v = vm["posix-echo-two"].as >(); int fd1 = boost::lexical_cast(v[0]); file_descriptor_sink sink1(fd1, close_handle); stream os1(sink1); os1 << v[1] << std::endl; int fd2 = boost::lexical_cast(v[2]); file_descriptor_sink sink2(fd2, close_handle); stream os2(sink2); os2 << v[3] << std::endl; } #elif defined(BOOST_WINDOWS_API) else if (vm["windows-print-showwindow"].as()) { STARTUPINFO si; GetStartupInfo(&si); std::cout << si.wShowWindow << std::endl; } else if (vm["windows-print-flags"].as()) { STARTUPINFO si; GetStartupInfo(&si); std::cout << si.dwFlags << std::endl; } #endif else if (vm.count("has-handle")) { #if defined(BOOST_WINDOWS_API) const auto handle = reinterpret_cast(vm["has-handle"].as()); #else const auto handle = static_cast(vm["has-handle"].as()); #endif auto all_handles = boost::this_process::get_handles(); return (std::find(all_handles.begin(), all_handles.end(), handle) != all_handles.end()) ? EXIT_SUCCESS : EXIT_FAILURE; } return EXIT_SUCCESS; }