Imported Upstream version 1.64.0
[platform/upstream/boost.git] / libs / process / test / sparring_partner.cpp
1 // Copyright (c) 2006, 2007 Julio M. Merino Vidal
2 // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
3 // Copyright (c) 2009 Boris Schaeling
4 // Copyright (c) 2010 Felipe Tanus, Boris Schaeling
5 // Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
10 #define BOOST_USE_WINDOWS_H
11
12 #include <boost/program_options.hpp>
13 #include <boost/filesystem.hpp>
14 #include <boost/algorithm/string/join.hpp>
15 #include <boost/range/iterator_range.hpp>
16 #include <boost/range/algorithm/transform.hpp>
17 #include <boost/range/algorithm_ext/push_back.hpp>
18 #include <boost/lambda/lambda.hpp>
19 #include <boost/process/environment.hpp>
20 #include <vector>
21 #include <string>
22 #include <iterator>
23 #include <iostream>
24 #include <cstdlib>
25 #if defined(BOOST_POSIX_API)
26 #   include <boost/lexical_cast.hpp>
27 #   include <boost/iostreams/device/file_descriptor.hpp>
28 #   include <boost/iostreams/stream.hpp>
29 #   include <unistd.h>
30 #elif defined(BOOST_WINDOWS_API)
31 #   include <Windows.h>
32 #endif
33
34
35 using namespace boost::program_options;
36
37 int main(int argc, char *argv[])
38 {
39     options_description desc;
40     desc.add_options()
41         ("echo-stdout", value<std::string>())
42         ("echo-stderr", value<std::string>())
43         ("echo-stdout-stderr", value<std::string>())
44         ("echo-argv", bool_switch())
45         ("exit-code", value<int>())
46         ("wait", value<int>())
47         ("is-closed-stdin", bool_switch())
48         ("is-closed-stdout", bool_switch())
49         ("is-closed-stderr", bool_switch())
50         ("is-nul-stdin", bool_switch())
51         ("is-nul-stdout", bool_switch())
52         ("is-nul-stderr", bool_switch())
53         ("loop", bool_switch())
54         ("prefix", value<std::string>())
55         ("prefix-once", value<std::string>())
56         ("pwd", bool_switch())
57         ("query", value<std::string>())
58         ("stdin-to-stdout", bool_switch())
59 #if defined(BOOST_POSIX_API)
60         ("posix-echo-one", value<std::vector<std::string> >()->multitoken())
61         ("posix-echo-two", value<std::vector<std::string> >()->multitoken());
62 #elif defined(BOOST_WINDOWS_API)
63         ("windows-print-showwindow", bool_switch())
64         ("windows-print-flags", bool_switch());
65 #endif
66     variables_map vm;
67     command_line_parser parser(argc, argv);
68     store(parser.options(desc).allow_unregistered().run(), vm);
69     notify(vm);
70
71     if (vm.count("echo-stdout"))
72     {
73         std::cout << vm["echo-stdout"].as<std::string>() << std::endl;
74     }
75     else if (vm.count("echo-stderr"))
76     {
77         std::cerr << vm["echo-stderr"].as<std::string>() << std::endl;
78     }
79     else if (vm.count("echo-stdout-stderr"))
80     {
81         std::cout << vm["echo-stdout-stderr"].as<std::string>() << std::endl;
82         std::cerr << vm["echo-stdout-stderr"].as<std::string>() << std::endl;
83     }
84     else if (vm["echo-argv"].as<bool>())
85     {
86         std::vector<char*> args(argv+1, argv + argc);
87         for (auto & arg : args)
88             std::cout << arg << std::endl;
89     }
90     else if (vm.count("exit-code"))
91     {
92         return vm["exit-code"].as<int>();
93     }
94     else if (vm.count("wait"))
95     {
96         int sec = vm["wait"].as<int>();
97 #if defined(BOOST_POSIX_API)
98         sleep(sec);
99 #elif defined(BOOST_WINDOWS_API)
100         Sleep(sec * 1000);
101 #endif
102     }
103     else if (vm["is-closed-stdin"].as<bool>())
104     {
105         std::string s;
106         std::cin >> s;
107         return std::cin.eof() ? EXIT_SUCCESS : EXIT_FAILURE;
108     }
109     else if (vm["is-closed-stdout"].as<bool>())
110     {
111         std::cout << "foo" << std::endl;
112         return std::cout.bad() ? EXIT_SUCCESS : EXIT_FAILURE;
113     }
114     else if (vm["is-closed-stderr"].as<bool>())
115     {
116         std::cerr << "foo" << std::endl;
117         return std::cerr.bad() ? EXIT_SUCCESS : EXIT_FAILURE;
118     }
119     else if (vm["is-nul-stdin"].as<bool>())
120     {
121 #if defined(BOOST_POSIX_API)
122         char buffer[1];
123         int res = read(STDIN_FILENO, buffer, 1);
124         return res != -1 ? EXIT_SUCCESS : EXIT_FAILURE;
125 #elif defined(BOOST_WINDOWS_API)
126         HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
127         if (h == INVALID_HANDLE_VALUE)
128             return EXIT_FAILURE;
129         char buffer[1];
130         DWORD read;
131         BOOL res = ReadFile(h, buffer, 1, &read, NULL);
132         CloseHandle(h);
133         return res ? EXIT_SUCCESS : EXIT_FAILURE;
134 #endif
135     }
136     else if (vm["is-nul-stdout"].as<bool>())
137     {
138         std::cout << "foo" << std::endl;
139         return std::cout.bad() ? EXIT_FAILURE : EXIT_SUCCESS;
140     }
141     else if (vm["is-nul-stderr"].as<bool>())
142     {
143         std::cerr << "foo" << std::endl;
144         return std::cerr.bad() ? EXIT_FAILURE : EXIT_SUCCESS;
145     }
146     else if (vm["loop"].as<bool>())
147     {
148         while (true);
149     }
150     else if (vm.count("prefix"))
151     {
152         std::string line;
153         while (std::getline(std::cin, line))
154             std::cout << vm["prefix"].as<std::string>() << line << std::endl;
155     }
156     else if (vm.count("prefix-once"))
157     {
158         std::string line;
159
160         std::getline(std::cin, line);
161
162         std::cout << vm["prefix-once"].as<std::string>() << line << std::endl;
163     }
164     else if (vm["pwd"].as<bool>())
165     {
166         std::cout << boost::filesystem::current_path().string() << std::endl;
167     }
168     else if (vm.count("query"))
169     {
170         auto key = vm["query"].as<std::string>();
171         auto env = boost::this_process::environment();
172         auto val = env[key];
173         if (val.empty())
174             std::cout << "************** empty environment **************" << std::endl;
175         else
176             std::cout << val.to_string() << std::endl;
177     }
178     else if (vm["stdin-to-stdout"].as<bool>())
179     {
180         char ch;
181         while (std::cin >> std::noskipws >> ch)
182             std::cout << ch << std::flush;
183     }
184 #if defined(BOOST_POSIX_API)
185     else if (vm.count("posix-echo-one"))
186     {
187         using namespace boost::iostreams;
188         std::vector<std::string> v = vm["posix-echo-one"].as<std::vector<std::string> >();
189         int fd = boost::lexical_cast<int>(v[0]);
190         file_descriptor_sink sink(fd, close_handle);
191         stream<file_descriptor_sink> os(sink);
192         os << v[1] << std::endl;
193     }
194     else if (vm.count("posix-echo-two"))
195     {
196         using namespace boost::iostreams;
197         std::vector<std::string> v = vm["posix-echo-two"].as<std::vector<std::string> >();
198         int fd1 = boost::lexical_cast<int>(v[0]);
199         file_descriptor_sink sink1(fd1, close_handle);
200         stream<file_descriptor_sink> os1(sink1);
201         os1 << v[1] << std::endl;
202         int fd2 = boost::lexical_cast<int>(v[2]);
203         file_descriptor_sink sink2(fd2, close_handle);
204         stream<file_descriptor_sink> os2(sink2);
205         os2 << v[3] << std::endl;
206     }
207 #elif defined(BOOST_WINDOWS_API)
208     else if (vm["windows-print-showwindow"].as<bool>())
209     {
210         STARTUPINFO si;
211         GetStartupInfo(&si);
212         std::cout << si.wShowWindow << std::endl;
213     }
214     else if (vm["windows-print-flags"].as<bool>())
215     {
216         STARTUPINFO si;
217         GetStartupInfo(&si);
218         std::cout << si.dwFlags << std::endl;
219     }
220 #endif
221     return EXIT_SUCCESS;
222 }