if (env_)
{ for (size_t i(0); i < len_; ++i)
{
assert(e[i]); // caller should make sure about len_
env_[i]= MY_STRDUP(e[i]); if (!env_[i])
{
errno_= errno;
WSREP_ERROR("Failed to allocate env. var: %s", e[i]); returntrue;
}
}
env_[len_]= NULL; returnfalse;
} else
{
errno_= errno;
WSREP_ERROR("Failed to allocate env. var vector of length: %zu", len_); returntrue;
}
}
void
env::dtor()
{ if (env_)
{ /* don't need to go beyond the first NULL */ for (size_t i(0); env_[i] != NULL; ++i) { MY_FREE(env_[i]); }
MY_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_; }
staticint
add_file_actions(posix_spawn_file_actions_t *fact, int close_fd, int dup_fd, int unused_fd)
{ // close child's stdout|stdin fd int err= posix_spawn_file_actions_addclose(fact, close_fd); if (err)
{
WSREP_ERROR ("posix_spawn_file_actions_addclose() failed: %d (%s)",
err, strerror(err)); return err;
}
// substitute our pipe descriptor in place of the closed one
err= posix_spawn_file_actions_adddup2(fact, dup_fd, close_fd); if (err)
{
WSREP_ERROR ("posix_spawn_file_actions_addup2() failed: %d (%s)",
err, strerror(err)); return err;
}
// close unused end of the pipe
err= posix_spawn_file_actions_addclose(fact, unused_fd); if (err)
{
WSREP_ERROR ("posix_spawn_file_actions_addclose(2) failed: %d (%s)",
err, strerror(err)); return err;
}
if (0 == strlen(str_))
{
WSREP_ERROR ("Can't start a process: null or empty command line."); return;
}
if (NULL == type ||
(strncmp(type, "w", 1) && strncmp(type, "r", 1) && strncmp(type, "rw", 2)))
{
WSREP_ERROR ("type argument should be either \"r\", \"w\" or \"rw\"."); return;
}
if (NULL == env) { env= environ; } // default to global environment
/* make sure that no signlas are masked in child process */
sigset_t sigmask_empty; sigemptyset(&sigmask_empty);
err_= posix_spawnattr_setsigmask(&attr, &sigmask_empty); if (err_)
{
WSREP_ERROR ("posix_spawnattr_setsigmask() failed: %d (%s)",
err_, strerror(err_)); goto cleanup_attr;
}
/* make sure the following signals are not ignored in child process */
sigset_t default_signals; sigemptyset(&default_signals);
sigaddset(&default_signals, SIGHUP);
sigaddset(&default_signals, SIGINT);
sigaddset(&default_signals, SIGQUIT);
sigaddset(&default_signals, SIGPIPE);
sigaddset(&default_signals, SIGTERM);
sigaddset(&default_signals, SIGCHLD);
err_= posix_spawnattr_setsigdefault(&attr, &default_signals); if (err_)
{
WSREP_ERROR ("posix_spawnattr_setsigdefault() failed: %d (%s)",
err_, strerror(err_)); goto cleanup_attr;
}
/* Add file actions for the child (fd substitution, close unused fds) */ if (read_from_child)
{
err_= add_file_actions(&fact, STDOUT_FD, read_pipe[WRITE_END],
read_pipe[READ_END]); if (err_) goto cleanup_fact;
}
if (write_to_child)
{
err_= add_file_actions(&fact, STDIN_FD, write_pipe[READ_END],
write_pipe[WRITE_END]); if (err_) goto cleanup_fact;
}
err_= posix_spawnp (&pid_, pargv[0], &fact, &attr, pargv, env); if (err_)
{
WSREP_ERROR ("posix_spawnp(%s) failed: %d (%s)",
pargv[2], err_, strerror(err_));
pid_= 0; // just to make sure it was not messed up in the call goto cleanup_fact;
}
if (read_from_child)
{
setup_parent_pipe_end(READ, read_pipe, READ_END, "r");
assert(from());
}
if (write_to_child)
{
setup_parent_pipe_end(WRITE, write_pipe, WRITE_END, "w");
assert(to());
}
cleanup_fact: int err; // to preserve err_ code
err= posix_spawn_file_actions_destroy (&fact); if (err)
{
WSREP_ERROR ("posix_spawn_file_actions_destroy() failed: %d (%s)\n",
err, strerror(err));
}
cleanup_pipes: if (read_pipe[0] >= 0) close (read_pipe[0]); if (read_pipe[1] >= 0) close (read_pipe[1]); if (write_pipe[0] >= 0) close (write_pipe[0]); if (write_pipe[1] >= 0) close (write_pipe[1]);
// Attempt 1: Try to get the IP from bind-address. // Skip if empty or bind-address=* if (my_bind_addr_str && my_bind_addr_str[0] != '\0' &&
strcmp(my_bind_addr_str, "*") != 0)
{ bool unused; unsignedintconst ip_type= wsrep_check_ip(my_bind_addr_str, &unused);
/* returns the length of the host part of the address string */
size_t wsrep_host_len(constchar* const addr, size_t const addr_len)
{ // check for IPv6 notation first constchar* const bracket= ('[' == addr[0] ? strchr(addr, ']') : NULL);
if (bracket) { // IPv6 return (bracket - addr + 1);
} else { // host part ends at ':' or end of string constchar* const colon= strchr(addr, ':'); return (colon ? colon - addr : addr_len);
}
}
/* return true if character can be a part of a filename */ bool wsrep_filename_char(constunsignedchar c)
{ return isalnum(c) || (c == '-') || (c == '_') || (c == '.');
}
/* return true if string is comma separated list */ bool wsrep_comma_char(constunsignedchar c)
{ return (c == ',');
}
/* return true if character can be a part of an address string */ bool wsrep_address_char(constunsignedchar c)
{ return wsrep_filename_char(c) ||
(c == ':') || (c == '[') || (c == ']') || (c == '/');
}
/* return true if character can be a part of an address string list */ bool wsrep_names_list(constunsignedchar c)
{ return wsrep_address_char(c) || wsrep_comma_char(c);
}
bool wsrep_check_request_str(constchar* const str, bool (*check) (constunsignedchar), bool log_warn)
{ for (size_t i(0); str[i] != '\0'; ++i)
{ if (!check(str[i]))
{ if (log_warn) WSREP_WARN("Illegal character in variable: %i (%c).",
str[i], str[i]); returntrue;
}
}
returnfalse;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.29 Sekunden
(vorverarbeitet am 2026-10-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.