Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / atf / dist / atf-c++ / process.cpp
blob89d33a684fd89538fc58d38c66e5d60ee5c8aec4
1 //
2 // Automated Testing Framework (atf)
3 //
4 // Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 // 1. Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // 2. Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
16 // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17 // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 extern "C" {
31 #include "atf-c/error.h"
32 #include "atf-c/process.h"
35 #include "atf-c++/exceptions.hpp"
36 #include "atf-c++/process.hpp"
37 #include "atf-c++/sanity.hpp"
39 namespace impl = atf::process;
40 #define IMPL_NAME "atf::process"
42 // ------------------------------------------------------------------------
43 // Auxiliary functions.
44 // ------------------------------------------------------------------------
46 template< class C >
47 atf::utils::auto_array< const char* >
48 collection_to_argv(const C& c)
50 atf::utils::auto_array< const char* > argv(new const char*[c.size() + 1]);
52 std::size_t pos = 0;
53 for (typename C::const_iterator iter = c.begin(); iter != c.end();
54 iter++) {
55 argv[pos] = (*iter).c_str();
56 pos++;
58 INV(pos == c.size());
59 argv[pos] = NULL;
61 return argv;
64 template< class C >
66 argv_to_collection(const char* const* argv)
68 C c;
70 for (const char* const* iter = argv; *iter != NULL; iter++)
71 c.push_back(std::string(*iter));
73 return c;
76 // ------------------------------------------------------------------------
77 // The "argv_array" type.
78 // ------------------------------------------------------------------------
80 impl::argv_array::argv_array(void) :
81 m_exec_argv(collection_to_argv(m_args))
85 impl::argv_array::argv_array(const char* arg1, ...)
87 m_args.push_back(arg1);
90 va_list ap;
91 const char* nextarg;
93 va_start(ap, arg1);
94 while ((nextarg = va_arg(ap, const char*)) != NULL)
95 m_args.push_back(nextarg);
96 va_end(ap);
99 ctor_init_exec_argv();
102 impl::argv_array::argv_array(const char* const* ca) :
103 m_args(argv_to_collection< args_vector >(ca)),
104 m_exec_argv(collection_to_argv(m_args))
108 impl::argv_array::argv_array(const argv_array& a) :
109 m_args(a.m_args),
110 m_exec_argv(collection_to_argv(m_args))
114 void
115 impl::argv_array::ctor_init_exec_argv(void)
117 m_exec_argv = collection_to_argv(m_args);
120 const char* const*
121 impl::argv_array::exec_argv(void)
122 const
124 return m_exec_argv.get();
127 impl::argv_array::size_type
128 impl::argv_array::size(void)
129 const
131 return m_args.size();
134 const char*
135 impl::argv_array::operator[](int idx)
136 const
138 return m_args[idx].c_str();
141 impl::argv_array::const_iterator
142 impl::argv_array::begin(void)
143 const
145 return m_args.begin();
148 impl::argv_array::const_iterator
149 impl::argv_array::end(void)
150 const
152 return m_args.end();
155 impl::argv_array&
156 impl::argv_array::operator=(const argv_array& a)
158 if (this != &a) {
159 m_args = a.m_args;
160 m_exec_argv = collection_to_argv(m_args);
162 return *this;
165 // ------------------------------------------------------------------------
166 // The "stream" types.
167 // ------------------------------------------------------------------------
169 impl::basic_stream::basic_stream(void) :
170 m_inited(false)
174 impl::basic_stream::~basic_stream(void)
176 if (m_inited)
177 atf_process_stream_fini(&m_sb);
180 const atf_process_stream_t*
181 impl::basic_stream::get_sb(void)
182 const
184 INV(m_inited);
185 return &m_sb;
188 impl::stream_capture::stream_capture(void)
190 atf_error_t err = atf_process_stream_init_capture(&m_sb);
191 if (atf_is_error(err))
192 throw_atf_error(err);
193 m_inited = true;
196 impl::stream_connect::stream_connect(const int src_fd, const int tgt_fd)
198 atf_error_t err = atf_process_stream_init_connect(&m_sb, src_fd, tgt_fd);
199 if (atf_is_error(err))
200 throw_atf_error(err);
201 m_inited = true;
204 impl::stream_inherit::stream_inherit(void)
206 atf_error_t err = atf_process_stream_init_inherit(&m_sb);
207 if (atf_is_error(err))
208 throw_atf_error(err);
209 m_inited = true;
212 impl::stream_redirect_fd::stream_redirect_fd(const int fd)
214 atf_error_t err = atf_process_stream_init_redirect_fd(&m_sb, fd);
215 if (atf_is_error(err))
216 throw_atf_error(err);
217 m_inited = true;
220 impl::stream_redirect_path::stream_redirect_path(const fs::path& p)
222 atf_error_t err = atf_process_stream_init_redirect_path(&m_sb, p.c_path());
223 if (atf_is_error(err))
224 throw_atf_error(err);
225 m_inited = true;
228 // ------------------------------------------------------------------------
229 // The "status" type.
230 // ------------------------------------------------------------------------
232 impl::status::status(atf_process_status_t& s) :
233 m_status(s)
237 impl::status::~status(void)
239 atf_process_status_fini(&m_status);
242 bool
243 impl::status::exited(void)
244 const
246 return atf_process_status_exited(&m_status);
250 impl::status::exitstatus(void)
251 const
253 return atf_process_status_exitstatus(&m_status);
256 bool
257 impl::status::signaled(void)
258 const
260 return atf_process_status_signaled(&m_status);
264 impl::status::termsig(void)
265 const
267 return atf_process_status_termsig(&m_status);
270 bool
271 impl::status::coredump(void)
272 const
274 return atf_process_status_coredump(&m_status);
277 // ------------------------------------------------------------------------
278 // The "child" type.
279 // ------------------------------------------------------------------------
281 impl::child::child(atf_process_child_t& c) :
282 m_child(c)
286 impl::child::~child(void)
290 impl::status
291 impl::child::wait(void)
293 atf_process_status_t s;
295 atf_error_t err = atf_process_child_wait(&m_child, &s);
296 if (atf_is_error(err))
297 throw_atf_error(err);
299 return status(s);
302 pid_t
303 impl::child::pid(void)
304 const
306 return atf_process_child_pid(&m_child);
309 atf::io::file_handle
310 impl::child::stdout_fd(void)
312 return io::file_handle(atf_process_child_stdout(&m_child));
315 atf::io::file_handle
316 impl::child::stderr_fd(void)
318 return io::file_handle(atf_process_child_stderr(&m_child));