*
* 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
#include <unistd.h>
#include <algorithm>
+#include <stdexcept>
#ifndef __USE_GNU
static char **environ= NULL;
iter != built_argv.end();
++iter)
{
- arg_buffer << *iter << " ";
+ if (*iter)
+ {
+ arg_buffer << *iter << " ";
+ }
}
return arg_buffer.str();
{
if (libtool() == NULL)
{
- fatal_message("libtool requested, but know libtool was found");
+ FATAL("libtool requested, but know libtool was found");
}
}
int error;
switch ((error= errno))
{
-#ifdef TARGET_OS_LINUX
+#ifdef __linux
case ERESTART:
#endif
case EINTR:
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;
}
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)
{
/*
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))
{
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);
}
}
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
{
void Application::Pipe::nonblock()
{
int flags;
+ do
{
flags= fcntl(_pipe_fd[READ], F_GETFL, 0);
} while (flags == -1 and (errno == EINTR or errno == EAGAIN));
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()
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));
}
}
{
std::stringstream arg_buffer;
- for (size_t x= _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();
return int(app.join());
}
-const char *gearmand_binary()
-{
- return GEARMAND_BINARY;
-}
-
-const char *drizzled_binary()
-{
- return DRIZZLED_BINARY;
-}
-
} // namespace exec_cmdline