123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- // 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;
- }
|