summaryrefslogtreecommitdiff
path: root/sql/wsrep_utils.cc
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-11-19 17:48:36 +0100
committerSergei Golubchik <serg@mariadb.org>2015-11-19 17:48:36 +0100
commit7f19330c595e3183d079fe2c18eecc74740e8f83 (patch)
tree8b853976cd14d96d5415757be525133b32be0c93 /sql/wsrep_utils.cc
parent4046ed12bcddfd831c510b022cb7af224be9457b (diff)
parentf4421c893b50f05078f14d33c47d21f52f59f8a7 (diff)
downloadmariadb-git-7f19330c595e3183d079fe2c18eecc74740e8f83.tar.gz
Merge branch 'github/10.0-galera' into 10.1
Diffstat (limited to 'sql/wsrep_utils.cc')
-rw-r--r--sql/wsrep_utils.cc93
1 files changed, 90 insertions, 3 deletions
diff --git a/sql/wsrep_utils.cc b/sql/wsrep_utils.cc
index 2998a5b04ac..56f1018deac 100644
--- a/sql/wsrep_utils.cc
+++ b/sql/wsrep_utils.cc
@@ -63,7 +63,7 @@ wsrep_prepend_PATH (const char* path)
size_t const new_path_len(strlen(old_path) + strlen(":") +
strlen(path) + 1);
- char* const new_path (reinterpret_cast<char*>(malloc(new_path_len)));
+ char* const new_path (static_cast<char*>(malloc(new_path_len)));
if (new_path)
{
@@ -89,6 +89,90 @@ wsrep_prepend_PATH (const char* path)
namespace wsp
{
+bool
+env::ctor_common(char** e)
+{
+ env_ = static_cast<char**>(malloc((len_ + 1) * sizeof(char*)));
+
+ if (env_)
+ {
+ for (size_t i(0); i < len_; ++i)
+ {
+ assert(e[i]); // caller should make sure about len_
+ env_[i] = strdup(e[i]);
+ if (!env_[i])
+ {
+ errno_ = errno;
+ WSREP_ERROR("Failed to allocate env. var: %s", e[i]);
+ return true;
+ }
+ }
+
+ env_[len_] = NULL;
+ return false;
+ }
+ else
+ {
+ errno_ = errno;
+ WSREP_ERROR("Failed to allocate env. var vector of length: %zu", len_);
+ return true;
+ }
+}
+
+void
+env::dtor()
+{
+ if (env_)
+ {
+ /* don't need to go beyond the first NULL */
+ for (size_t i(0); env_[i] != NULL; ++i) { free(env_[i]); }
+ free(env_);
+ env_ = NULL;
+ }
+ len_ = 0;
+}
+
+env::env(char** e)
+ : len_(0), env_(NULL), errno_(0)
+{
+ if (!e) { e = environ; }
+ /* count the size of the vector */
+ while (e[len_]) { ++len_; }
+
+ if (ctor_common(e)) dtor();
+}
+
+env::env(const env& e)
+ : len_(e.len_), env_(0), errno_(0)
+{
+ if (ctor_common(e.env_)) dtor();
+}
+
+env::~env() { dtor(); }
+
+int
+env::append(const char* val)
+{
+ char** tmp = static_cast<char**>(realloc(env_, (len_ + 2)*sizeof(char*)));
+
+ if (tmp)
+ {
+ env_ = tmp;
+ env_[len_] = strdup(val);
+
+ if (env_[len_])
+ {
+ ++len_;
+ env_[len_] = NULL;
+ }
+ else errno_ = errno;
+ }
+ else errno_ = errno;
+
+ return errno_;
+}
+
+
#define PIPE_READ 0
#define PIPE_WRITE 1
#define STDIN_FD 0
@@ -98,7 +182,7 @@ namespace wsp
# define POSIX_SPAWN_USEVFORK 0
#endif
-process::process (const char* cmd, const char* type)
+process::process (const char* cmd, const char* type, char** env)
: str_(cmd ? strdup(cmd) : strdup("")), io_(NULL), err_(EINVAL), pid_(0)
{
if (0 == str_)
@@ -120,6 +204,8 @@ process::process (const char* cmd, const char* type)
return;
}
+ if (NULL == env) { env = environ; } // default to global environment
+
int pipe_fds[2] = { -1, };
if (::pipe(pipe_fds))
{
@@ -215,7 +301,7 @@ process::process (const char* cmd, const char* type)
goto cleanup_fact;
}
- err_ = posix_spawnp (&pid_, pargv[0], &fact, &attr, pargv, environ);
+ err_ = posix_spawnp (&pid_, pargv[0], &fact, &attr, pargv, env);
if (err_)
{
WSREP_ERROR ("posix_spawnp(%s) failed: %d (%s)",
@@ -309,6 +395,7 @@ process::wait ()
{
case 126: err_ = EACCES; break; /* Permission denied */
case 127: err_ = ENOENT; break; /* No such file or directory */
+ case 143: err_ = EINTR; break; /* Subprocess killed */
}
WSREP_ERROR("Process completed with error: %s: %d (%s)",
str_, err_, strerror(err_));