diff options
author | Nirbhay Choubey <nirbhay@mariadb.com> | 2015-09-09 20:51:39 -0400 |
---|---|---|
committer | Nirbhay Choubey <nirbhay@mariadb.com> | 2015-09-09 20:51:39 -0400 |
commit | fa5f18d6734249aa326d6296c9b9c2338cb33b10 (patch) | |
tree | 63233fb5a049d4683cc6faa910875702a7836d8c /sql/wsrep_utils.cc | |
parent | f533b2b462b5b73630245172b627506d36f95b39 (diff) | |
parent | 37ae601a8766f37cdd919efc801133d2a8cfaf70 (diff) | |
download | mariadb-git-fa5f18d6734249aa326d6296c9b9c2338cb33b10.tar.gz |
Merge branch '5.5-galera' into 10.0-galera
Diffstat (limited to 'sql/wsrep_utils.cc')
-rw-r--r-- | sql/wsrep_utils.cc | 93 |
1 files changed, 90 insertions, 3 deletions
diff --git a/sql/wsrep_utils.cc b/sql/wsrep_utils.cc index 7a87d38d430..719e8e6b473 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_)); |