Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / unit / atf-src / atf-sh / atf-sh.cpp
blobd7bc7fc82bc0016c1129ef4eb57ce9b79a8f1038
1 //
2 // Automated Testing Framework (atf)
3 //
4 // Copyright (c) 2010 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 <unistd.h>
34 #include <cerrno>
35 #include <cstdlib>
36 #include <cstring>
37 #include <iostream>
39 #include "atf-c++/config.hpp"
41 #include "atf-c++/detail/application.hpp"
42 #include "atf-c++/detail/fs.hpp"
43 #include "atf-c++/detail/sanity.hpp"
45 // ------------------------------------------------------------------------
46 // Auxiliary functions.
47 // ------------------------------------------------------------------------
49 namespace {
51 static
52 std::string
53 fix_plain_name(const char *filename)
55 const atf::fs::path filepath(filename);
56 if (filepath.branch_path().str() == ".")
57 return std::string("./") + filename;
58 else
59 return std::string(filename);
62 static
63 std::string*
64 construct_script(const char* filename)
66 const std::string libexecdir = atf::config::get("atf_libexecdir");
67 const std::string pkgdatadir = atf::config::get("atf_pkgdatadir");
68 const std::string shell = atf::config::get("atf_shell");
70 std::string* command = new std::string();
71 command->reserve(512);
72 (*command) += ("Atf_Check='" + libexecdir + "/atf-check' ; " +
73 "Atf_Shell='" + shell + "' ; " +
74 ". " + pkgdatadir + "/libatf-sh.subr ; " +
75 ". " + fix_plain_name(filename) + " ; " +
76 "main \"${@}\"");
77 return command;
80 static
81 const char**
82 construct_argv(const std::string& shell, const int interpreter_argc,
83 const char* const* interpreter_argv)
85 PRE(interpreter_argc >= 1);
86 PRE(interpreter_argv[0] != NULL);
88 const std::string* script = construct_script(interpreter_argv[0]);
90 const int count = 4 + (interpreter_argc - 1) + 1;
91 const char** argv = new const char*[count];
92 argv[0] = shell.c_str();
93 argv[1] = "-c";
94 argv[2] = script->c_str();
95 argv[3] = interpreter_argv[0];
97 for (int i = 1; i < interpreter_argc; i++)
98 argv[4 + i - 1] = interpreter_argv[i];
100 argv[count - 1] = NULL;
102 return argv;
105 } // anonymous namespace
107 // ------------------------------------------------------------------------
108 // The "atf_sh" class.
109 // ------------------------------------------------------------------------
111 class atf_sh : public atf::application::app {
112 static const char* m_description;
114 public:
115 atf_sh(void);
117 int main(void);
120 const char* atf_sh::m_description =
121 "atf-sh is a shell interpreter that extends the functionality of the "
122 "system sh(1) with the atf-sh library.";
124 atf_sh::atf_sh(void) :
125 app(m_description, "atf-sh(1)", "atf(7)")
130 atf_sh::main(void)
132 if (m_argc < 1)
133 throw atf::application::usage_error("No test program provided");
135 const atf::fs::path script(m_argv[0]);
136 if (!atf::fs::exists(script))
137 throw std::runtime_error("The test program '" + script.str() + "' "
138 "does not exist");
140 const std::string shell = atf::config::get("atf_shell");
141 const char** argv = construct_argv(shell, m_argc, m_argv);
142 // Don't bother keeping track of the memory allocated by construct_argv:
143 // we are going to exec or die immediately.
145 const int ret = execv(shell.c_str(), const_cast< char** >(argv));
146 INV(ret == -1);
147 std::cerr << "Failed to execute " << shell << ": " << std::strerror(errno)
148 << "\n";
149 return EXIT_FAILURE;
153 main(int argc, char* const* argv)
155 return atf_sh().run(argc, argv);