X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libtest%2Fcmdline.cc;h=29a22de657df8f823b50bd7c60d2011c723e3b49;hb=c3472bb8e7417a272f8c76c5a1316e3370adc941;hp=709aac10a9e4a18579f1fe29dbf4455b152c59a7;hpb=482d0b2efc0a5b1e16818551892613c252c15f30;p=awesomized%2Flibmemcached diff --git a/libtest/cmdline.cc b/libtest/cmdline.cc index 709aac10..29a22de6 100644 --- a/libtest/cmdline.cc +++ b/libtest/cmdline.cc @@ -2,7 +2,7 @@ * * Data Differential YATL (i.e. libtest) library * - * Copyright (C) 2012 Data Differential, http://datadifferential.com/ + * Copyright (C) 2012-2013 Data Differential, http://datadifferential.com/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -34,7 +34,8 @@ * */ -#include "mem_config.h" +#include "libtest/yatlcon.h" + #include "libtest/common.h" using namespace libtest; @@ -58,6 +59,7 @@ using namespace libtest; #include #include +#include #ifndef __USE_GNU static char **environ= NULL; @@ -74,10 +76,13 @@ namespace { std::stringstream arg_buffer; for (vchar_ptr_t::iterator iter= built_argv.begin(); - iter == built_argv.end(); - iter++) + iter != built_argv.end(); + ++iter) { - arg_buffer << *iter << " "; + if (*iter) + { + arg_buffer << *iter << " "; + } } return arg_buffer.str(); @@ -137,7 +142,7 @@ Application::Application(const std::string& arg, const bool _use_libtool_arg) : { if (libtool() == NULL) { - fatal_message("libtool requested, but know libtool was found"); + FATAL("libtool requested, but know libtool was found"); } } @@ -357,7 +362,7 @@ bool Application::slurp() int error; switch ((error= errno)) { -#ifdef TARGET_OS_LINUX +#ifdef __linux case ERESTART: #endif case EINTR: @@ -365,15 +370,15 @@ bool Application::slurp() case EFAULT: case ENOMEM: - fatal_message(strerror(error)); + FATAL(strerror(error)); break; case EINVAL: - fatal_message("RLIMIT_NOFILE exceeded, or if OSX the timeout value was invalid"); + FATAL("RLIMIT_NOFILE exceeded, or if OSX the timeout value was invalid"); break; default: - fatal_message(strerror(error)); + FATAL(strerror(error)); break; } @@ -407,8 +412,8 @@ bool Application::slurp() Application::error_t Application::join() { - pid_t waited_pid= waitpid(_pid, &_status, 0); - + pid_t waited_pid= waitpid(_pid, &_status, WUNTRACED); + slurp(); if (waited_pid == _pid and WIFEXITED(_status) == false) { /* @@ -423,25 +428,47 @@ Application::error_t Application::join() std::string error_string("posix_spawn() failed pid:"); error_string+= _pid; error_string+= " name:"; - error_string+= built_argv[0]; + error_string+= print_argv(built_argv); + if (stderr_result_length()) + { + error_string+= " stderr: "; + error_string+= stderr_c_str(); + } throw std::logic_error(error_string); } - else if WIFSIGNALED(_status) + else if (WIFSIGNALED(_status)) { if (WTERMSIG(_status) != SIGTERM and WTERMSIG(_status) != SIGHUP) { + slurp(); _app_exit_state= Application::INVALID_POSIX_SPAWN; - std::string error_string(built_argv[0]); + std::string error_string(print_argv(built_argv)); error_string+= " was killed by signal "; error_string+= strsignal(WTERMSIG(_status)); + + if (stdout_result_length()) + { + error_string+= " stdout: "; + error_string+= stdout_c_str(); + } + + if (stderr_result_length()) + { + error_string+= " stderr: "; + error_string+= stderr_c_str(); + } + throw std::runtime_error(error_string); } -#if 0 // If we terminted it on purpose then it counts as a success. - Out << "waitpid() application terminated at request" - << " pid:" << _pid - << " name:" << built_argv[0]; +#if defined(DEBUG) + if (DEBUG) + { + Out << "waitpid() application terminated at request" + << " pid:" << _pid + << " name:" << built_argv[0]; + } #endif } else @@ -458,8 +485,20 @@ Application::error_t Application::join() } else if (waited_pid == -1) { + std::string error_string; + if (stdout_result_length()) + { + error_string+= " stdout: "; + error_string+= stdout_c_str(); + } + + if (stderr_result_length()) + { + error_string+= " stderr: "; + error_string+= stderr_c_str(); + } + Error << "waitpid() returned errno:" << strerror(errno) << " " << error_string; _app_exit_state= Application::UNKNOWN; - Error << "waitpid() returned errno:" << strerror(errno); } else { @@ -517,9 +556,10 @@ bool Application::Pipe::read(libtest::vchar_t& arg) bool data_was_read= false; + libtest::vchar_t buffer; + buffer.resize(1024); ssize_t read_length; - char buffer[1024]= { 0 }; - while ((read_length= ::read(_pipe_fd[READ], buffer, sizeof(buffer)))) + while ((read_length= ::read(_pipe_fd[READ], &buffer[0], buffer.size()))) { if (read_length == -1) { @@ -551,6 +591,7 @@ bool Application::Pipe::read(libtest::vchar_t& arg) void Application::Pipe::nonblock() { int flags; + do { flags= fcntl(_pipe_fd[READ], F_GETFL, 0); } while (flags == -1 and (errno == EINTR or errno == EAGAIN)); @@ -579,23 +620,21 @@ void Application::Pipe::reset() close(READ); close(WRITE); -#if defined(HAVE_PIPE2) && HAVE_PIPE2 +#ifdef HAVE_PIPE2 if (pipe2(_pipe_fd, O_NONBLOCK|O_CLOEXEC) == -1) -#else - if (pipe(_pipe_fd) == -1) #endif { - fatal_message(strerror(errno)); - } - _open[0]= true; - _open[1]= true; + if (pipe(_pipe_fd) == -1) + { + FATAL(strerror(errno)); + } -#if defined(HAVE_PIPE2) && HAVE_PIPE2 - { + // Since either pipe2() was not found/called we set the pipe directly nonblock(); cloexec(); } -#endif + _open[0]= true; + _open[1]= true; } void Application::Pipe::cloexec() @@ -651,14 +690,12 @@ void Application::Pipe::dup_for_spawn(posix_spawn_file_actions_t& file_actions) 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)); + FATAL("posix_spawn_file_actions_adddup2(%s)", 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)); + FATAL("posix_spawn_file_actions_addclose(%s)", strerror(ret)); } } @@ -683,8 +720,8 @@ void Application::create_argv(const char *args[]) if (_use_libtool) { assert(libtool()); - built_argv.push_back(strdup(libtool())); - built_argv.push_back(strdup("--mode=execute")); + vchar::append(built_argv, libtool()); + vchar::append(built_argv, "--mode=execute"); } if (_use_valgrind) @@ -692,52 +729,54 @@ void Application::create_argv(const char *args[]) /* valgrind --error-exitcode=1 --leak-check=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")); + vchar::append(built_argv, "valgrind"); + vchar::append(built_argv, "--error-exitcode=1"); + vchar::append(built_argv, "--leak-check=yes"); #if 0 - built_argv.push_back(strdup("--show-reachable=yes")); + vchar::append(built_argv, "--show-reachable=yes")); #endif - built_argv.push_back(strdup("--track-fds=yes")); + vchar::append(built_argv, "--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")); + vchar::append(built_argv, "--malloc-fill=A5"); + vchar::append(built_argv, "--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)); + libtest::vchar_t buffer; + buffer.resize(1024); + int length= snprintf(&buffer[0], buffer.size(), "--log-file=%s", log_file.c_str()); + fatal_assert(length > 0 and size_t(length) < buffer.size()); + vchar::append(built_argv, &buffer[0]); } 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")); + vchar::append(built_argv, "valgrind"); + vchar::append(built_argv, "--error-exitcode=1"); + vchar::append(built_argv, "--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)); + libtest::vchar_t buffer; + buffer.resize(1024); + int length= snprintf(&buffer[0], buffer.size(), "--log-file=%s", log_file.c_str()); + fatal_assert(length > 0 and size_t(length) < buffer.size()); + vchar::append(built_argv, &buffer[0]); } else if (_use_gdb) { - built_argv.push_back(strdup("gdb")); + vchar::append(built_argv, "gdb"); } - built_argv.push_back(strdup(_exectuble_with_path.c_str())); + vchar::append(built_argv, _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())); + vchar::append(built_argv, (*iter).first.c_str()); if ((*iter).second.empty() == false) { - built_argv.push_back(strdup((*iter).second.c_str())); + vchar::append(built_argv, (*iter).second.c_str()); } } @@ -745,7 +784,7 @@ void Application::create_argv(const char *args[]) { for (const char **ptr= args; *ptr; ++ptr) { - built_argv.push_back(strdup(*ptr)); + vchar::append(built_argv, *ptr); } } built_argv.push_back(NULL); @@ -760,28 +799,21 @@ std::string Application::arguments() { std::stringstream arg_buffer; - for (size_t x= (1 +_use_libtool) ? 2 : 0; - x < _argc and built_argv[x]; - ++x) + // Skip printing out the libtool reference + for (size_t x= _use_libtool ? 2 : 0; x < _argc; ++x) { - arg_buffer << built_argv[x] << " "; + if (built_argv[x]) + { + arg_buffer << built_argv[x] << " "; + } } return arg_buffer.str(); } -struct DeleteFromVector -{ - template - void operator() ( T* ptr) const - { - free(ptr); - } -}; - void Application::delete_argv() { - std::for_each(built_argv.begin(), built_argv.end(), DeleteFromVector()); + std::for_each(built_argv.begin(), built_argv.end(), FreeFromVector()); built_argv.clear(); _argc= 0; @@ -802,14 +834,4 @@ int exec_cmdline(const std::string& command, const char *args[], bool use_libtoo return int(app.join()); } -const char *gearmand_binary() -{ - return GEARMAND_BINARY; -} - -const char *drizzled_binary() -{ - return DRIZZLED_BINARY; -} - } // namespace exec_cmdline