diff options
Diffstat (limited to 'src/boost/libs/process/test/sparring_partner.cpp')
-rw-r--r-- | src/boost/libs/process/test/sparring_partner.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/src/boost/libs/process/test/sparring_partner.cpp b/src/boost/libs/process/test/sparring_partner.cpp new file mode 100644 index 00000000..c628832a --- /dev/null +++ b/src/boost/libs/process/test/sparring_partner.cpp @@ -0,0 +1,239 @@ +// 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 <boost/program_options.hpp> +#include <boost/filesystem.hpp> +#include <boost/algorithm/string/join.hpp> +#include <boost/range/iterator_range.hpp> +#include <boost/range/algorithm/transform.hpp> +#include <boost/range/algorithm_ext/push_back.hpp> +#include <boost/lambda/lambda.hpp> +#include <boost/process/environment.hpp> +#include <boost/process/handles.hpp> +#include <vector> +#include <string> +#include <iterator> +#include <iostream> +#include <cstdlib> +#if defined(BOOST_POSIX_API) +# include <boost/lexical_cast.hpp> +# include <boost/iostreams/device/file_descriptor.hpp> +# include <boost/iostreams/stream.hpp> +# include <unistd.h> +#elif defined(BOOST_WINDOWS_API) +# include <windows.h> +#endif + + +using namespace boost::program_options; + +int main(int argc, char *argv[]) +{ + options_description desc; + desc.add_options() + ("echo-stdout", value<std::string>()) + ("echo-stderr", value<std::string>()) + ("echo-stdout-stderr", value<std::string>()) + ("echo-argv", bool_switch()) + ("exit-code", value<int>()) + ("wait", value<int>()) + ("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<std::string>()) + ("prefix-once", value<std::string>()) + ("pwd", bool_switch()) + ("query", value<std::string>()) + ("stdin-to-stdout", bool_switch()) + ("has-handle", value<std::uintptr_t>()) +#if defined(BOOST_POSIX_API) + ("posix-echo-one", value<std::vector<std::string> >()->multitoken()) + ("posix-echo-two", value<std::vector<std::string> >()->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::string>() << std::endl; + } + else if (vm.count("echo-stderr")) + { + std::cerr << vm["echo-stderr"].as<std::string>() << std::endl; + } + else if (vm.count("echo-stdout-stderr")) + { + std::cout << vm["echo-stdout-stderr"].as<std::string>() << std::endl; + std::cerr << vm["echo-stdout-stderr"].as<std::string>() << std::endl; + } + else if (vm["echo-argv"].as<bool>()) + { + std::vector<char*> 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<int>(); + } + else if (vm.count("wait")) + { + int sec = vm["wait"].as<int>(); +#if defined(BOOST_POSIX_API) + sleep(sec); +#elif defined(BOOST_WINDOWS_API) + Sleep(sec * 1000); +#endif + } + else if (vm["is-closed-stdin"].as<bool>()) + { + std::string s; + std::cin >> s; + return std::cin.eof() ? EXIT_SUCCESS : EXIT_FAILURE; + } + else if (vm["is-closed-stdout"].as<bool>()) + { + std::cout << "foo" << std::endl; + return std::cout.bad() ? EXIT_SUCCESS : EXIT_FAILURE; + } + else if (vm["is-closed-stderr"].as<bool>()) + { + std::cerr << "foo" << std::endl; + return std::cerr.bad() ? EXIT_SUCCESS : EXIT_FAILURE; + } + else if (vm["is-nul-stdin"].as<bool>()) + { +#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<bool>()) + { + std::cout << "foo" << std::endl; + return std::cout.bad() ? EXIT_FAILURE : EXIT_SUCCESS; + } + else if (vm["is-nul-stderr"].as<bool>()) + { + std::cerr << "foo" << std::endl; + return std::cerr.bad() ? EXIT_FAILURE : EXIT_SUCCESS; + } + else if (vm["loop"].as<bool>()) + { + while (true); + } + else if (vm["abort"].as<bool>()) + { + std::abort(); + } + else if (vm.count("prefix")) + { + std::string line; + while (std::getline(std::cin, line)) + std::cout << vm["prefix"].as<std::string>() << line << std::endl; + } + else if (vm.count("prefix-once")) + { + std::string line; + + std::getline(std::cin, line); + + std::cout << vm["prefix-once"].as<std::string>() << line << std::endl; + } + else if (vm["pwd"].as<bool>()) + { + std::cout << boost::filesystem::current_path().string() << std::endl; + } + else if (vm.count("query")) + { + auto key = vm["query"].as<std::string>(); + 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<bool>()) + { + 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<std::string> v = vm["posix-echo-one"].as<std::vector<std::string> >(); + int fd = boost::lexical_cast<int>(v[0]); + file_descriptor_sink sink(fd, close_handle); + stream<file_descriptor_sink> os(sink); + os << v[1] << std::endl; + } + else if (vm.count("posix-echo-two")) + { + using namespace boost::iostreams; + std::vector<std::string> v = vm["posix-echo-two"].as<std::vector<std::string> >(); + int fd1 = boost::lexical_cast<int>(v[0]); + file_descriptor_sink sink1(fd1, close_handle); + stream<file_descriptor_sink> os1(sink1); + os1 << v[1] << std::endl; + int fd2 = boost::lexical_cast<int>(v[2]); + file_descriptor_sink sink2(fd2, close_handle); + stream<file_descriptor_sink> os2(sink2); + os2 << v[3] << std::endl; + } +#elif defined(BOOST_WINDOWS_API) + else if (vm["windows-print-showwindow"].as<bool>()) + { + STARTUPINFO si; + GetStartupInfo(&si); + std::cout << si.wShowWindow << std::endl; + } + else if (vm["windows-print-flags"].as<bool>()) + { + 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<boost::this_process::native_handle_type>(vm["has-handle"].as<std::uintptr_t>()); +#else + const auto handle = static_cast<boost::this_process::native_handle_type>(vm["has-handle"].as<std::uintptr_t>()); +#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; +} |