summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/process/test/sparring_partner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/process/test/sparring_partner.cpp')
-rw-r--r--src/boost/libs/process/test/sparring_partner.cpp239
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;
+}