diff options
Diffstat (limited to 'gdb/common/environ.c')
-rw-r--r-- | gdb/common/environ.c | 202 |
1 files changed, 78 insertions, 124 deletions
diff --git a/gdb/common/environ.c b/gdb/common/environ.c index 3145d01..20f8aba 100644 --- a/gdb/common/environ.c +++ b/gdb/common/environ.c @@ -18,165 +18,119 @@ #include "common-defs.h" #include "environ.h" #include <algorithm> - +#include <utility> -/* Return a new environment object. */ +/* See common/environ.h. */ -struct gdb_environ * -make_environ (void) +gdb_environ & +gdb_environ::operator= (gdb_environ &&e) { - struct gdb_environ *e; - - e = XNEW (struct gdb_environ); - - e->allocated = 10; - e->vector = (char **) xmalloc ((e->allocated + 1) * sizeof (char *)); - e->vector[0] = 0; - return e; + /* Are we self-moving? */ + if (&e == this) + return *this; + + m_environ_vector = std::move (e.m_environ_vector); + e.m_environ_vector.clear (); + e.m_environ_vector.push_back (NULL); + return *this; } -/* Free an environment and all the strings in it. */ +/* See common/environ.h. */ -void -free_environ (struct gdb_environ *e) -{ - char **vector = e->vector; - - while (*vector) - xfree (*vector++); - - xfree (e->vector); - xfree (e); -} - -/* Copy the environment given to this process into E. - Also copies all the strings in it, so we can be sure - that all strings in these environments are safe to free. */ - -void -init_environ (struct gdb_environ *e) +gdb_environ gdb_environ::from_host_environ () { extern char **environ; - int i; + gdb_environ e; if (environ == NULL) - return; - - for (i = 0; environ[i]; i++) /*EMPTY */ ; + return e; - if (e->allocated < i) + for (int i = 0; environ[i] != NULL; ++i) { - e->allocated = std::max (i, e->allocated + 10); - e->vector = (char **) xrealloc ((char *) e->vector, - (e->allocated + 1) * sizeof (char *)); + /* Make sure we add the element before the last (NULL). */ + e.m_environ_vector.insert (e.m_environ_vector.end () - 1, + xstrdup (environ[i])); } - memcpy (e->vector, environ, (i + 1) * sizeof (char *)); + return e; +} - while (--i >= 0) - { - int len = strlen (e->vector[i]); - char *newobj = (char *) xmalloc (len + 1); +/* See common/environ.h. */ - memcpy (newobj, e->vector[i], len + 1); - e->vector[i] = newobj; - } +void +gdb_environ::clear () +{ + for (char *v : m_environ_vector) + xfree (v); + m_environ_vector.clear (); + /* Always add the NULL element. */ + m_environ_vector.push_back (NULL); } -/* Return the vector of environment E. - This is used to get something to pass to execve. */ +/* Helper function to check if STRING contains an environment variable + assignment of VAR, i.e., if STRING starts with 'VAR='. Return true + if it contains, false otherwise. */ -char ** -environ_vector (struct gdb_environ *e) +static bool +match_var_in_string (char *string, const char *var, size_t var_len) { - return e->vector; + if (strncmp (string, var, var_len) == 0 && string[var_len] == '=') + return true; + + return false; } - -/* Return the value in environment E of variable VAR. */ -char * -get_in_environ (const struct gdb_environ *e, const char *var) +/* See common/environ.h. */ + +const char * +gdb_environ::get (const char *var) const { - int len = strlen (var); - char **vector = e->vector; - char *s; + size_t len = strlen (var); - for (; (s = *vector) != NULL; vector++) - if (strncmp (s, var, len) == 0 && s[len] == '=') - return &s[len + 1]; + for (char *el : m_environ_vector) + if (el != NULL && match_var_in_string (el, var, len)) + return &el[len + 1]; - return 0; + return NULL; } -/* Store the value in E of VAR as VALUE. */ +/* See common/environ.h. */ void -set_in_environ (struct gdb_environ *e, const char *var, const char *value) +gdb_environ::set (const char *var, const char *value) { - int i; - int len = strlen (var); - char **vector = e->vector; - char *s; + /* We have to unset the variable in the vector if it exists. */ + unset (var); - for (i = 0; (s = vector[i]) != NULL; i++) - if (strncmp (s, var, len) == 0 && s[len] == '=') - break; - - if (s == 0) - { - if (i == e->allocated) - { - e->allocated += 10; - vector = (char **) xrealloc ((char *) vector, - (e->allocated + 1) * sizeof (char *)); - e->vector = vector; - } - vector[i + 1] = 0; - } - else - xfree (s); - - s = (char *) xmalloc (len + strlen (value) + 2); - strcpy (s, var); - strcat (s, "="); - strcat (s, value); - vector[i] = s; - - /* This used to handle setting the PATH and GNUTARGET variables - specially. The latter has been replaced by "set gnutarget" - (which has worked since GDB 4.11). The former affects searching - the PATH to find SHELL, and searching the PATH to find the - argument of "symbol-file" or "exec-file". Maybe we should have - some kind of "set exec-path" for that. But in any event, having - "set env" affect anything besides the inferior is a bad idea. - What if we want to change the environment we pass to the program - without afecting GDB's behavior? */ - - return; + /* Insert the element before the last one, which is always NULL. */ + m_environ_vector.insert (m_environ_vector.end () - 1, + concat (var, "=", value, NULL)); } -/* Remove the setting for variable VAR from environment E. */ +/* See common/environ.h. */ void -unset_in_environ (struct gdb_environ *e, const char *var) +gdb_environ::unset (const char *var) { - int len = strlen (var); - char **vector = e->vector; - char *s; + size_t len = strlen (var); + + /* We iterate until '.cend () - 1' because the last element is + always NULL. */ + for (std::vector<char *>::const_iterator el = m_environ_vector.cbegin (); + el != m_environ_vector.cend () - 1; + ++el) + if (match_var_in_string (*el, var, len)) + { + xfree (*el); + m_environ_vector.erase (el); + break; + } +} - for (; (s = *vector) != NULL; vector++) - { - if (strncmp (s, var, len) == 0 && s[len] == '=') - { - xfree (s); - /* Walk through the vector, shuffling args down by one, including - the NULL terminator. Can't use memcpy() here since the regions - overlap, and memmove() might not be available. */ - while ((vector[0] = vector[1]) != NULL) - { - vector++; - } - break; - } - } +/* See common/environ.h. */ + +char ** +gdb_environ::envp () const +{ + return const_cast<char **> (&m_environ_vector[0]); } |