2 // Automated Testing Framework (atf)
4 // Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
5 // All rights reserved.
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
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.
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 // ------------------------------------------------------------------------
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]);
53 for (typename
C::const_iterator iter
= c
.begin(); iter
!= c
.end();
55 argv
[pos
] = (*iter
).c_str();
66 argv_to_collection(const char* const* argv
)
70 for (const char* const* iter
= argv
; *iter
!= NULL
; iter
++)
71 c
.push_back(std::string(*iter
));
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
);
94 while ((nextarg
= va_arg(ap
, const char*)) != NULL
)
95 m_args
.push_back(nextarg
);
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
) :
110 m_exec_argv(collection_to_argv(m_args
))
115 impl::argv_array::ctor_init_exec_argv(void)
117 m_exec_argv
= collection_to_argv(m_args
);
121 impl::argv_array::exec_argv(void)
124 return m_exec_argv
.get();
127 impl::argv_array::size_type
128 impl::argv_array::size(void)
131 return m_args
.size();
135 impl::argv_array::operator[](int idx
)
138 return m_args
[idx
].c_str();
141 impl::argv_array::const_iterator
142 impl::argv_array::begin(void)
145 return m_args
.begin();
148 impl::argv_array::const_iterator
149 impl::argv_array::end(void)
156 impl::argv_array::operator=(const argv_array
& a
)
160 m_exec_argv
= collection_to_argv(m_args
);
165 // ------------------------------------------------------------------------
166 // The "stream" types.
167 // ------------------------------------------------------------------------
169 impl::basic_stream::basic_stream(void) :
174 impl::basic_stream::~basic_stream(void)
177 atf_process_stream_fini(&m_sb
);
180 const atf_process_stream_t
*
181 impl::basic_stream::get_sb(void)
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
);
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
);
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
);
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
);
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
);
228 // ------------------------------------------------------------------------
229 // The "status" type.
230 // ------------------------------------------------------------------------
232 impl::status::status(atf_process_status_t
& s
) :
237 impl::status::~status(void)
239 atf_process_status_fini(&m_status
);
243 impl::status::exited(void)
246 return atf_process_status_exited(&m_status
);
250 impl::status::exitstatus(void)
253 return atf_process_status_exitstatus(&m_status
);
257 impl::status::signaled(void)
260 return atf_process_status_signaled(&m_status
);
264 impl::status::termsig(void)
267 return atf_process_status_termsig(&m_status
);
271 impl::status::coredump(void)
274 return atf_process_status_coredump(&m_status
);
277 // ------------------------------------------------------------------------
279 // ------------------------------------------------------------------------
281 impl::child::child(atf_process_child_t
& c
) :
286 impl::child::~child(void)
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
);
303 impl::child::pid(void)
306 return atf_process_child_pid(&m_child
);
310 impl::child::stdout_fd(void)
312 return io::file_handle(atf_process_child_stdout(&m_child
));
316 impl::child::stderr_fd(void)
318 return io::file_handle(atf_process_child_stderr(&m_child
));