+
+void Application::Pipe::reset()
+{
+ close(READ);
+ close(WRITE);
+
+#if defined(HAVE_PIPE2) && HAVE_PIPE2
+ if (pipe2(_pipe_fd, O_NONBLOCK) == -1)
+#else
+ if (pipe(_pipe_fd) == -1)
+#endif
+ {
+ fatal_message(strerror(errno));
+ }
+ _open[0]= true;
+ _open[1]= true;
+
+ if (true)
+ {
+ nonblock();
+ cloexec();
+ }
+}
+
+void Application::Pipe::cloexec()
+{
+ int ret;
+ if ((ret= fcntl(_pipe_fd[WRITE], F_GETFD, 0)) == -1)
+ {
+ Error << "fcntl(F_GETFD) " << strerror(errno);
+ throw strerror(errno);
+ }
+
+ if ((ret= fcntl(_pipe_fd[WRITE], F_SETFD, ret | FD_CLOEXEC)) == -1)
+ {
+ Error << "fcntl(F_SETFD) " << strerror(errno);
+ throw strerror(errno);
+ }
+}
+
+Application::Pipe::~Pipe()
+{
+ if (_pipe_fd[0] != -1)
+ {
+ ::close(_pipe_fd[0]);
+ }
+
+ if (_pipe_fd[1] != -1)
+ {
+ ::close(_pipe_fd[1]);
+ }
+}
+
+void Application::Pipe::dup_for_spawn(posix_spawn_file_actions_t& file_actions)
+{
+ int type= STDIN_FILENO == _std_fd ? 0 : 1;
+
+ int ret;
+ if ((ret= posix_spawn_file_actions_adddup2(&file_actions, _pipe_fd[type], _std_fd )) < 0)
+ {
+ Error << "posix_spawn_file_actions_adddup2(" << strerror(ret) << ")";
+ fatal_message(strerror(ret));
+ }
+
+ if ((ret= posix_spawn_file_actions_addclose(&file_actions, _pipe_fd[type])) < 0)
+ {
+ Error << "posix_spawn_file_actions_adddup2(" << strerror(ret) << ")";
+ fatal_message(strerror(ret));
+ }
+}
+
+void Application::Pipe::close(const close_t& arg)
+{
+ int type= int(arg);
+
+ if (_open[type])
+ {
+ if (::close(_pipe_fd[type]) == -1)
+ {
+ Error << "close(" << strerror(errno) << ")";
+ }
+ _open[type]= false;
+ _pipe_fd[type]= -1;
+ }
+}
+
+void Application::create_argv(const char *args[])
+{
+ delete_argv();
+ if (_use_libtool)
+ {
+ assert(libtool());
+ built_argv.push_back(strdup(libtool()));
+ built_argv.push_back(strdup("--mode=execute"));
+ }
+
+ if (_use_valgrind)
+ {
+ /*
+ valgrind --error-exitcode=1 --leak-check=yes --show-reachable=yes --track-fds=yes --malloc-fill=A5 --free-fill=DE
+ */
+ built_argv.push_back(strdup("valgrind"));
+ built_argv.push_back(strdup("--error-exitcode=1"));
+ built_argv.push_back(strdup("--leak-check=yes"));
+ built_argv.push_back(strdup("--show-reachable=yes"));
+ built_argv.push_back(strdup("--track-fds=yes"));
+#if 0
+ built_argv[x++]= strdup("--track-origin=yes");
+#endif
+ built_argv.push_back(strdup("--malloc-fill=A5"));
+ built_argv.push_back(strdup("--free-fill=DE"));
+
+ std::string log_file= create_tmpfile("valgrind");
+ char buffer[1024];
+ int length= snprintf(buffer, sizeof(buffer), "--log-file=%s", log_file.c_str());
+ fatal_assert(length > 0 and size_t(length) < sizeof(buffer));
+ built_argv.push_back(strdup(buffer));
+ }
+ else if (_use_ptrcheck)
+ {
+ /*
+ valgrind --error-exitcode=1 --tool=exp-ptrcheck --log-file=
+ */
+ built_argv.push_back(strdup("valgrind"));
+ built_argv.push_back(strdup("--error-exitcode=1"));
+ built_argv.push_back(strdup("--tool=exp-ptrcheck"));
+ std::string log_file= create_tmpfile("ptrcheck");
+ char buffer[1024];
+ int length= snprintf(buffer, sizeof(buffer), "--log-file=%s", log_file.c_str());
+ fatal_assert(length > 0 and size_t(length) < sizeof(buffer));
+ built_argv.push_back(strdup(buffer));
+ }
+ else if (_use_gdb)
+ {
+ built_argv.push_back(strdup("gdb"));
+ }
+
+ built_argv.push_back(strdup(_exectuble_with_path.c_str()));
+
+ for (Options::const_iterator iter= _options.begin(); iter != _options.end(); ++iter)
+ {
+ built_argv.push_back(strdup((*iter).first.c_str()));
+ if ((*iter).second.empty() == false)
+ {
+ built_argv.push_back(strdup((*iter).second.c_str()));
+ }
+ }
+
+ if (args)
+ {
+ for (const char **ptr= args; *ptr; ++ptr)
+ {
+ built_argv.push_back(strdup(*ptr));
+ }
+ }
+ built_argv.push_back(NULL);
+}
+
+std::string Application::print()
+{
+ return print_argv(built_argv);
+}
+
+std::string Application::arguments()
+{
+ std::stringstream arg_buffer;
+
+ for (size_t x= (1 +_use_libtool) ? 2 : 0;
+ x < _argc and built_argv[x];
+ ++x)
+ {
+ arg_buffer << built_argv[x] << " ";
+ }
+
+ return arg_buffer.str();
+}
+
+struct DeleteFromVector
+{
+ template <class T>
+ void operator() ( T* ptr) const
+ {
+ free(ptr);
+ }
+};
+
+void Application::delete_argv()
+{
+ std::for_each(built_argv.begin(), built_argv.end(), DeleteFromVector());
+
+ built_argv.clear();
+ _argc= 0;
+}
+
+
+int exec_cmdline(const std::string& command, const char *args[], bool use_libtool)
+{
+ Application app(command, use_libtool);
+
+ Application::error_t ret= app.run(args);
+
+ if (ret != Application::SUCCESS)
+ {
+ return int(ret);
+ }
+
+ return int(app.join());
+}
+
+const char *gearmand_binary()
+{
+ return GEARMAND_BINARY;
+}
+
+const char *drizzled_binary()
+{
+ return DRIZZLED_BINARY;
+}
+
+} // namespace exec_cmdline