1 // Copyright (c) 2008 The NetBSD Foundation, Inc.
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions
7 // 1. Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 // 2. Redistributions in binary form must reproduce the above copyright
10 // notice, this list of conditions and the following disclaimer in the
11 // documentation and/or other materials provided with the distribution.
13 // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14 // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24 // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #if !defined(ATF_CXX_DETAIL_PROCESS_HPP)
27 #define ATF_CXX_DETAIL_PROCESS_HPP
30 #include <sys/types.h>
32 #include <atf-c/detail/process.h>
33 #include <atf-c/error.h>
39 #include <atf-c++/detail/auto_array.hpp>
40 #include <atf-c++/detail/exceptions.hpp>
41 #include <atf-c++/detail/fs.hpp>
49 // ------------------------------------------------------------------------
50 // The "argv_array" type.
51 // ------------------------------------------------------------------------
54 typedef std::vector< std::string > args_vector;
57 // TODO: This is immutable, so we should be able to use
58 // std::tr1::shared_array instead when it becomes widely available.
59 // The reason would be to remove all copy constructors and assignment
60 // operators from this class.
61 auto_array< const char* > m_exec_argv;
62 void ctor_init_exec_argv(void);
65 typedef args_vector::const_iterator const_iterator;
66 typedef args_vector::size_type size_type;
69 argv_array(const char*, ...);
70 explicit argv_array(const char* const*);
71 template< class C > explicit argv_array(const C&);
72 argv_array(const argv_array&);
74 const char* const* exec_argv(void) const;
75 size_type size(void) const;
76 const char* operator[](int) const;
78 const_iterator begin(void) const;
79 const_iterator end(void) const;
81 argv_array& operator=(const argv_array&);
85 argv_array::argv_array(const C& c)
87 for (typename C::const_iterator iter = c.begin(); iter != c.end();
89 m_args.push_back(*iter);
90 ctor_init_exec_argv();
93 // ------------------------------------------------------------------------
94 // The "stream" types.
95 // ------------------------------------------------------------------------
99 atf_process_stream_t m_sb;
102 const atf_process_stream_t* get_sb(void) const;
109 class stream_capture : basic_stream {
110 // Allow access to the getters.
111 template< class OutStream, class ErrStream > friend
112 child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
113 template< class OutStream, class ErrStream > friend
114 status exec(const atf::fs::path&, const argv_array&,
115 const OutStream&, const ErrStream&, void (*)(void));
118 stream_capture(void);
121 class stream_connect : basic_stream {
122 // Allow access to the getters.
123 template< class OutStream, class ErrStream > friend
124 child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
125 template< class OutStream, class ErrStream > friend
126 status exec(const atf::fs::path&, const argv_array&,
127 const OutStream&, const ErrStream&, void (*)(void));
130 stream_connect(const int, const int);
133 class stream_inherit : basic_stream {
134 // Allow access to the getters.
135 template< class OutStream, class ErrStream > friend
136 child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
137 template< class OutStream, class ErrStream > friend
138 status exec(const atf::fs::path&, const argv_array&,
139 const OutStream&, const ErrStream&, void (*)(void));
142 stream_inherit(void);
145 class stream_redirect_fd : basic_stream {
146 // Allow access to the getters.
147 template< class OutStream, class ErrStream > friend
148 child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
149 template< class OutStream, class ErrStream > friend
150 status exec(const atf::fs::path&, const argv_array&,
151 const OutStream&, const ErrStream&, void (*)(void));
154 stream_redirect_fd(const int);
157 class stream_redirect_path : basic_stream {
158 // Allow access to the getters.
159 template< class OutStream, class ErrStream > friend
160 child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
161 template< class OutStream, class ErrStream > friend
162 status exec(const atf::fs::path&, const argv_array&,
163 const OutStream&, const ErrStream&, void (*)(void));
166 stream_redirect_path(const fs::path&);
169 // ------------------------------------------------------------------------
170 // The "status" type.
171 // ------------------------------------------------------------------------
174 atf_process_status_t m_status;
177 template< class OutStream, class ErrStream > friend
178 status exec(const atf::fs::path&, const argv_array&,
179 const OutStream&, const ErrStream&, void (*)(void));
181 status(atf_process_status_t&);
186 bool exited(void) const;
187 int exitstatus(void) const;
189 bool signaled(void) const;
190 int termsig(void) const;
191 bool coredump(void) const;
194 // ------------------------------------------------------------------------
196 // ------------------------------------------------------------------------
199 atf_process_child_t m_child;
202 template< class OutStream, class ErrStream > friend
203 child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
205 child(atf_process_child_t& c);
212 pid_t pid(void) const;
217 // ------------------------------------------------------------------------
219 // ------------------------------------------------------------------------
222 void flush_streams(void);
223 } // namespace detail
225 // TODO: The void* cookie can probably be templatized, thus also allowing
226 // const data structures.
227 template< class OutStream, class ErrStream >
229 fork(void (*start)(void*), const OutStream& outsb,
230 const ErrStream& errsb, void* v)
232 atf_process_child_t c;
234 detail::flush_streams();
235 atf_error_t err = atf_process_fork(&c, start, outsb.get_sb(),
237 if (atf_is_error(err))
238 throw_atf_error(err);
243 template< class OutStream, class ErrStream >
245 exec(const atf::fs::path& prog, const argv_array& argv,
246 const OutStream& outsb, const ErrStream& errsb,
247 void (*prehook)(void))
249 atf_process_status_t s;
251 detail::flush_streams();
252 atf_error_t err = atf_process_exec_array(&s, prog.c_path(),
257 if (atf_is_error(err))
258 throw_atf_error(err);
263 template< class OutStream, class ErrStream >
265 exec(const atf::fs::path& prog, const argv_array& argv,
266 const OutStream& outsb, const ErrStream& errsb)
268 return exec(prog, argv, outsb, errsb, NULL);
271 } // namespace process
274 #endif // !defined(ATF_CXX_DETAIL_PROCESS_HPP)