Home | History | Annotate | Line # | Download | only in detail
      1  1.1  jmmv //
      2  1.1  jmmv // Automated Testing Framework (atf)
      3  1.1  jmmv //
      4  1.3  jmmv // Copyright (c) 2008 The NetBSD Foundation, Inc.
      5  1.1  jmmv // All rights reserved.
      6  1.1  jmmv //
      7  1.1  jmmv // Redistribution and use in source and binary forms, with or without
      8  1.1  jmmv // modification, are permitted provided that the following conditions
      9  1.1  jmmv // are met:
     10  1.1  jmmv // 1. Redistributions of source code must retain the above copyright
     11  1.1  jmmv //    notice, this list of conditions and the following disclaimer.
     12  1.1  jmmv // 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  jmmv //    notice, this list of conditions and the following disclaimer in the
     14  1.1  jmmv //    documentation and/or other materials provided with the distribution.
     15  1.1  jmmv //
     16  1.1  jmmv // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
     17  1.1  jmmv // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
     18  1.1  jmmv // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19  1.1  jmmv // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20  1.1  jmmv // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
     21  1.1  jmmv // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22  1.1  jmmv // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     23  1.1  jmmv // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24  1.1  jmmv // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
     25  1.1  jmmv // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     26  1.1  jmmv // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27  1.1  jmmv // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  1.1  jmmv //
     29  1.1  jmmv 
     30  1.1  jmmv #if !defined(_ATF_CXX_PROCESS_HPP_)
     31  1.1  jmmv #define _ATF_CXX_PROCESS_HPP_
     32  1.1  jmmv 
     33  1.1  jmmv extern "C" {
     34  1.1  jmmv #include <sys/types.h>
     35  1.1  jmmv 
     36  1.1  jmmv #include "../../atf-c/error.h"
     37  1.1  jmmv 
     38  1.1  jmmv #include "../../atf-c/detail/process.h"
     39  1.1  jmmv }
     40  1.1  jmmv 
     41  1.1  jmmv #include <string>
     42  1.1  jmmv #include <vector>
     43  1.1  jmmv 
     44  1.4  jmmv #include "auto_array.hpp"
     45  1.1  jmmv #include "exceptions.hpp"
     46  1.1  jmmv #include "fs.hpp"
     47  1.1  jmmv 
     48  1.1  jmmv namespace atf {
     49  1.1  jmmv namespace process {
     50  1.1  jmmv 
     51  1.1  jmmv class child;
     52  1.1  jmmv class status;
     53  1.1  jmmv 
     54  1.1  jmmv // ------------------------------------------------------------------------
     55  1.1  jmmv // The "argv_array" type.
     56  1.1  jmmv // ------------------------------------------------------------------------
     57  1.1  jmmv 
     58  1.1  jmmv class argv_array {
     59  1.1  jmmv     typedef std::vector< std::string > args_vector;
     60  1.1  jmmv     args_vector m_args;
     61  1.1  jmmv 
     62  1.1  jmmv     // TODO: This is immutable, so we should be able to use
     63  1.1  jmmv     // std::tr1::shared_array instead when it becomes widely available.
     64  1.1  jmmv     // The reason would be to remove all copy constructors and assignment
     65  1.1  jmmv     // operators from this class.
     66  1.4  jmmv     auto_array< const char* > m_exec_argv;
     67  1.1  jmmv     void ctor_init_exec_argv(void);
     68  1.1  jmmv 
     69  1.1  jmmv public:
     70  1.1  jmmv     typedef args_vector::const_iterator const_iterator;
     71  1.1  jmmv     typedef args_vector::size_type size_type;
     72  1.1  jmmv 
     73  1.1  jmmv     argv_array(void);
     74  1.1  jmmv     argv_array(const char*, ...);
     75  1.1  jmmv     explicit argv_array(const char* const*);
     76  1.1  jmmv     template< class C > explicit argv_array(const C&);
     77  1.1  jmmv     argv_array(const argv_array&);
     78  1.1  jmmv 
     79  1.1  jmmv     const char* const* exec_argv(void) const;
     80  1.1  jmmv     size_type size(void) const;
     81  1.1  jmmv     const char* operator[](int) const;
     82  1.1  jmmv 
     83  1.1  jmmv     const_iterator begin(void) const;
     84  1.1  jmmv     const_iterator end(void) const;
     85  1.1  jmmv 
     86  1.1  jmmv     argv_array& operator=(const argv_array&);
     87  1.1  jmmv };
     88  1.1  jmmv 
     89  1.1  jmmv template< class C >
     90  1.1  jmmv argv_array::argv_array(const C& c)
     91  1.1  jmmv {
     92  1.1  jmmv     for (typename C::const_iterator iter = c.begin(); iter != c.end();
     93  1.1  jmmv          iter++)
     94  1.1  jmmv         m_args.push_back(*iter);
     95  1.1  jmmv     ctor_init_exec_argv();
     96  1.1  jmmv }
     97  1.1  jmmv 
     98  1.1  jmmv // ------------------------------------------------------------------------
     99  1.1  jmmv // The "stream" types.
    100  1.1  jmmv // ------------------------------------------------------------------------
    101  1.1  jmmv 
    102  1.1  jmmv class basic_stream {
    103  1.1  jmmv protected:
    104  1.1  jmmv     atf_process_stream_t m_sb;
    105  1.1  jmmv     bool m_inited;
    106  1.1  jmmv 
    107  1.1  jmmv     const atf_process_stream_t* get_sb(void) const;
    108  1.1  jmmv 
    109  1.1  jmmv public:
    110  1.1  jmmv     basic_stream(void);
    111  1.1  jmmv     ~basic_stream(void);
    112  1.1  jmmv };
    113  1.1  jmmv 
    114  1.1  jmmv class stream_capture : basic_stream {
    115  1.1  jmmv     // Allow access to the getters.
    116  1.1  jmmv     template< class OutStream, class ErrStream > friend
    117  1.1  jmmv     child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
    118  1.1  jmmv     template< class OutStream, class ErrStream > friend
    119  1.1  jmmv     status exec(const atf::fs::path&, const argv_array&,
    120  1.2  jmmv                 const OutStream&, const ErrStream&, void (*)(void));
    121  1.1  jmmv 
    122  1.1  jmmv public:
    123  1.1  jmmv     stream_capture(void);
    124  1.1  jmmv };
    125  1.1  jmmv 
    126  1.1  jmmv class stream_connect : basic_stream {
    127  1.1  jmmv     // Allow access to the getters.
    128  1.1  jmmv     template< class OutStream, class ErrStream > friend
    129  1.1  jmmv     child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
    130  1.1  jmmv     template< class OutStream, class ErrStream > friend
    131  1.1  jmmv     status exec(const atf::fs::path&, const argv_array&,
    132  1.2  jmmv                 const OutStream&, const ErrStream&, void (*)(void));
    133  1.1  jmmv 
    134  1.1  jmmv public:
    135  1.1  jmmv     stream_connect(const int, const int);
    136  1.1  jmmv };
    137  1.1  jmmv 
    138  1.1  jmmv class stream_inherit : basic_stream {
    139  1.1  jmmv     // Allow access to the getters.
    140  1.1  jmmv     template< class OutStream, class ErrStream > friend
    141  1.1  jmmv     child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
    142  1.1  jmmv     template< class OutStream, class ErrStream > friend
    143  1.1  jmmv     status exec(const atf::fs::path&, const argv_array&,
    144  1.2  jmmv                 const OutStream&, const ErrStream&, void (*)(void));
    145  1.1  jmmv 
    146  1.1  jmmv public:
    147  1.1  jmmv     stream_inherit(void);
    148  1.1  jmmv };
    149  1.1  jmmv 
    150  1.1  jmmv class stream_redirect_fd : basic_stream {
    151  1.1  jmmv     // Allow access to the getters.
    152  1.1  jmmv     template< class OutStream, class ErrStream > friend
    153  1.1  jmmv     child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
    154  1.1  jmmv     template< class OutStream, class ErrStream > friend
    155  1.1  jmmv     status exec(const atf::fs::path&, const argv_array&,
    156  1.2  jmmv                 const OutStream&, const ErrStream&, void (*)(void));
    157  1.1  jmmv 
    158  1.1  jmmv public:
    159  1.1  jmmv     stream_redirect_fd(const int);
    160  1.1  jmmv };
    161  1.1  jmmv 
    162  1.1  jmmv class stream_redirect_path : basic_stream {
    163  1.1  jmmv     // Allow access to the getters.
    164  1.1  jmmv     template< class OutStream, class ErrStream > friend
    165  1.1  jmmv     child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
    166  1.1  jmmv     template< class OutStream, class ErrStream > friend
    167  1.1  jmmv     status exec(const atf::fs::path&, const argv_array&,
    168  1.2  jmmv                 const OutStream&, const ErrStream&, void (*)(void));
    169  1.1  jmmv 
    170  1.1  jmmv public:
    171  1.1  jmmv     stream_redirect_path(const fs::path&);
    172  1.1  jmmv };
    173  1.1  jmmv 
    174  1.1  jmmv // ------------------------------------------------------------------------
    175  1.1  jmmv // The "status" type.
    176  1.1  jmmv // ------------------------------------------------------------------------
    177  1.1  jmmv 
    178  1.1  jmmv class status {
    179  1.1  jmmv     atf_process_status_t m_status;
    180  1.1  jmmv 
    181  1.1  jmmv     friend class child;
    182  1.1  jmmv     template< class OutStream, class ErrStream > friend
    183  1.1  jmmv     status exec(const atf::fs::path&, const argv_array&,
    184  1.2  jmmv                 const OutStream&, const ErrStream&, void (*)(void));
    185  1.1  jmmv 
    186  1.1  jmmv     status(atf_process_status_t&);
    187  1.1  jmmv 
    188  1.1  jmmv public:
    189  1.1  jmmv     ~status(void);
    190  1.1  jmmv 
    191  1.1  jmmv     bool exited(void) const;
    192  1.1  jmmv     int exitstatus(void) const;
    193  1.1  jmmv 
    194  1.1  jmmv     bool signaled(void) const;
    195  1.1  jmmv     int termsig(void) const;
    196  1.1  jmmv     bool coredump(void) const;
    197  1.1  jmmv };
    198  1.1  jmmv 
    199  1.1  jmmv // ------------------------------------------------------------------------
    200  1.1  jmmv // The "child" type.
    201  1.1  jmmv // ------------------------------------------------------------------------
    202  1.1  jmmv 
    203  1.1  jmmv class child {
    204  1.1  jmmv     atf_process_child_t m_child;
    205  1.1  jmmv     bool m_waited;
    206  1.1  jmmv 
    207  1.1  jmmv     template< class OutStream, class ErrStream > friend
    208  1.1  jmmv     child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
    209  1.1  jmmv 
    210  1.1  jmmv     child(atf_process_child_t& c);
    211  1.1  jmmv 
    212  1.1  jmmv public:
    213  1.1  jmmv     ~child(void);
    214  1.1  jmmv 
    215  1.1  jmmv     status wait(void);
    216  1.1  jmmv 
    217  1.1  jmmv     pid_t pid(void) const;
    218  1.1  jmmv     int stdout_fd(void);
    219  1.1  jmmv     int stderr_fd(void);
    220  1.1  jmmv };
    221  1.1  jmmv 
    222  1.1  jmmv // ------------------------------------------------------------------------
    223  1.1  jmmv // Free functions.
    224  1.1  jmmv // ------------------------------------------------------------------------
    225  1.1  jmmv 
    226  1.1  jmmv namespace detail {
    227  1.1  jmmv void flush_streams(void);
    228  1.1  jmmv } // namespace detail
    229  1.1  jmmv 
    230  1.1  jmmv // TODO: The void* cookie can probably be templatized, thus also allowing
    231  1.1  jmmv // const data structures.
    232  1.1  jmmv template< class OutStream, class ErrStream >
    233  1.1  jmmv child
    234  1.1  jmmv fork(void (*start)(void*), const OutStream& outsb,
    235  1.1  jmmv      const ErrStream& errsb, void* v)
    236  1.1  jmmv {
    237  1.1  jmmv     atf_process_child_t c;
    238  1.1  jmmv 
    239  1.1  jmmv     detail::flush_streams();
    240  1.1  jmmv     atf_error_t err = atf_process_fork(&c, start, outsb.get_sb(),
    241  1.1  jmmv                                        errsb.get_sb(), v);
    242  1.1  jmmv     if (atf_is_error(err))
    243  1.1  jmmv         throw_atf_error(err);
    244  1.1  jmmv 
    245  1.1  jmmv     return child(c);
    246  1.1  jmmv }
    247  1.1  jmmv 
    248  1.1  jmmv template< class OutStream, class ErrStream >
    249  1.1  jmmv status
    250  1.1  jmmv exec(const atf::fs::path& prog, const argv_array& argv,
    251  1.2  jmmv      const OutStream& outsb, const ErrStream& errsb,
    252  1.2  jmmv      void (*prehook)(void))
    253  1.1  jmmv {
    254  1.1  jmmv     atf_process_status_t s;
    255  1.1  jmmv 
    256  1.1  jmmv     detail::flush_streams();
    257  1.1  jmmv     atf_error_t err = atf_process_exec_array(&s, prog.c_path(),
    258  1.1  jmmv                                              argv.exec_argv(),
    259  1.1  jmmv                                              outsb.get_sb(),
    260  1.2  jmmv                                              errsb.get_sb(),
    261  1.2  jmmv                                              prehook);
    262  1.1  jmmv     if (atf_is_error(err))
    263  1.1  jmmv         throw_atf_error(err);
    264  1.1  jmmv 
    265  1.1  jmmv     return status(s);
    266  1.1  jmmv }
    267  1.1  jmmv 
    268  1.2  jmmv template< class OutStream, class ErrStream >
    269  1.2  jmmv status
    270  1.2  jmmv exec(const atf::fs::path& prog, const argv_array& argv,
    271  1.2  jmmv      const OutStream& outsb, const ErrStream& errsb)
    272  1.2  jmmv {
    273  1.2  jmmv     return exec(prog, argv, outsb, errsb, NULL);
    274  1.2  jmmv }
    275  1.2  jmmv 
    276  1.1  jmmv } // namespace process
    277  1.1  jmmv } // namespace atf
    278  1.1  jmmv 
    279  1.1  jmmv #endif // !defined(_ATF_CXX_PROCESS_HPP_)
    280