xref: /netbsd-src/external/gpl3/gdb/dist/gdbsupport/environ.cc (revision 5ba1f45f2a09259cc846f20c7c5501604d633c90)
18dffb485Schristos /* environ.c -- library for manipulating environments for GNU.
28dffb485Schristos 
3*5ba1f45fSchristos    Copyright (C) 1986-2024 Free Software Foundation, Inc.
48dffb485Schristos 
58dffb485Schristos    This program is free software; you can redistribute it and/or modify
68dffb485Schristos    it under the terms of the GNU General Public License as published by
78dffb485Schristos    the Free Software Foundation; either version 3 of the License, or
88dffb485Schristos    (at your option) any later version.
98dffb485Schristos 
108dffb485Schristos    This program is distributed in the hope that it will be useful,
118dffb485Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
128dffb485Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
138dffb485Schristos    GNU General Public License for more details.
148dffb485Schristos 
158dffb485Schristos    You should have received a copy of the GNU General Public License
168dffb485Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
178dffb485Schristos 
188dffb485Schristos #include "environ.h"
198dffb485Schristos #include <algorithm>
208dffb485Schristos #include <utility>
218dffb485Schristos 
228dffb485Schristos /* See gdbsupport/environ.h.  */
238dffb485Schristos 
248dffb485Schristos gdb_environ &
258dffb485Schristos gdb_environ::operator= (gdb_environ &&e)
268dffb485Schristos {
278dffb485Schristos   /* Are we self-moving?  */
288dffb485Schristos   if (&e == this)
298dffb485Schristos     return *this;
308dffb485Schristos 
314b169a6bSchristos   this->clear ();
324b169a6bSchristos 
338dffb485Schristos   m_environ_vector = std::move (e.m_environ_vector);
348dffb485Schristos   m_user_set_env = std::move (e.m_user_set_env);
358dffb485Schristos   m_user_unset_env = std::move (e.m_user_unset_env);
368dffb485Schristos   e.m_environ_vector.clear ();
378dffb485Schristos   e.m_environ_vector.push_back (NULL);
388dffb485Schristos   e.m_user_set_env.clear ();
398dffb485Schristos   e.m_user_unset_env.clear ();
408dffb485Schristos   return *this;
418dffb485Schristos }
428dffb485Schristos 
438dffb485Schristos /* See gdbsupport/environ.h.  */
448dffb485Schristos 
458dffb485Schristos gdb_environ gdb_environ::from_host_environ ()
468dffb485Schristos {
478dffb485Schristos   extern char **environ;
488dffb485Schristos   gdb_environ e;
498dffb485Schristos 
508dffb485Schristos   if (environ == NULL)
518dffb485Schristos     return e;
528dffb485Schristos 
538dffb485Schristos   for (int i = 0; environ[i] != NULL; ++i)
548dffb485Schristos     {
558dffb485Schristos       /* Make sure we add the element before the last (NULL).  */
568dffb485Schristos       e.m_environ_vector.insert (e.m_environ_vector.end () - 1,
578dffb485Schristos 				 xstrdup (environ[i]));
588dffb485Schristos     }
598dffb485Schristos 
608dffb485Schristos   return e;
618dffb485Schristos }
628dffb485Schristos 
638dffb485Schristos /* See gdbsupport/environ.h.  */
648dffb485Schristos 
658dffb485Schristos void
668dffb485Schristos gdb_environ::clear ()
678dffb485Schristos {
688dffb485Schristos   for (char *v : m_environ_vector)
698dffb485Schristos     xfree (v);
708dffb485Schristos   m_environ_vector.clear ();
718dffb485Schristos   /* Always add the NULL element.  */
728dffb485Schristos   m_environ_vector.push_back (NULL);
738dffb485Schristos   m_user_set_env.clear ();
748dffb485Schristos   m_user_unset_env.clear ();
758dffb485Schristos }
768dffb485Schristos 
778dffb485Schristos /* Helper function to check if STRING contains an environment variable
788dffb485Schristos    assignment of VAR, i.e., if STRING starts with 'VAR='.  Return true
798dffb485Schristos    if it contains, false otherwise.  */
808dffb485Schristos 
818dffb485Schristos static bool
828dffb485Schristos match_var_in_string (const char *string, const char *var, size_t var_len)
838dffb485Schristos {
848dffb485Schristos   if (strncmp (string, var, var_len) == 0 && string[var_len] == '=')
858dffb485Schristos     return true;
868dffb485Schristos 
878dffb485Schristos   return false;
888dffb485Schristos }
898dffb485Schristos 
908dffb485Schristos /* See gdbsupport/environ.h.  */
918dffb485Schristos 
928dffb485Schristos const char *
938dffb485Schristos gdb_environ::get (const char *var) const
948dffb485Schristos {
958dffb485Schristos   size_t len = strlen (var);
968dffb485Schristos 
978dffb485Schristos   for (char *el : m_environ_vector)
988dffb485Schristos     if (el != NULL && match_var_in_string (el, var, len))
998dffb485Schristos       return &el[len + 1];
1008dffb485Schristos 
1018dffb485Schristos   return NULL;
1028dffb485Schristos }
1038dffb485Schristos 
1048dffb485Schristos /* See gdbsupport/environ.h.  */
1058dffb485Schristos 
1068dffb485Schristos void
1078dffb485Schristos gdb_environ::set (const char *var, const char *value)
1088dffb485Schristos {
1098dffb485Schristos   char *fullvar = concat (var, "=", value, (char *) NULL);
1108dffb485Schristos 
1118dffb485Schristos   /* We have to unset the variable in the vector if it exists.  */
1128dffb485Schristos   unset (var, false);
1138dffb485Schristos 
1148dffb485Schristos   /* Insert the element before the last one, which is always NULL.  */
1158dffb485Schristos   m_environ_vector.insert (m_environ_vector.end () - 1, fullvar);
1168dffb485Schristos 
1178dffb485Schristos   /* Mark this environment variable as having been set by the user.
1188dffb485Schristos      This will be useful when we deal with setting environment
1198dffb485Schristos      variables on the remote target.  */
1208dffb485Schristos   m_user_set_env.insert (std::string (fullvar));
1218dffb485Schristos 
1228dffb485Schristos   /* If this environment variable is marked as unset by the user, then
1238dffb485Schristos      remove it from the list, because now the user wants to set
1248dffb485Schristos      it.  */
1258dffb485Schristos   m_user_unset_env.erase (std::string (var));
1268dffb485Schristos }
1278dffb485Schristos 
1288dffb485Schristos /* See gdbsupport/environ.h.  */
1298dffb485Schristos 
1308dffb485Schristos void
1318dffb485Schristos gdb_environ::unset (const char *var, bool update_unset_list)
1328dffb485Schristos {
1338dffb485Schristos   size_t len = strlen (var);
1348dffb485Schristos   std::vector<char *>::iterator it_env;
1358dffb485Schristos 
1368dffb485Schristos   /* We iterate until '.end () - 1' because the last element is
1378dffb485Schristos      always NULL.  */
1388dffb485Schristos   for (it_env = m_environ_vector.begin ();
1398dffb485Schristos        it_env != m_environ_vector.end () - 1;
1408dffb485Schristos        ++it_env)
1418dffb485Schristos     if (match_var_in_string (*it_env, var, len))
1428dffb485Schristos       break;
1438dffb485Schristos 
1448dffb485Schristos   if (it_env != m_environ_vector.end () - 1)
1458dffb485Schristos     {
1468dffb485Schristos       m_user_set_env.erase (std::string (*it_env));
1478dffb485Schristos       xfree (*it_env);
1488dffb485Schristos 
1498dffb485Schristos       m_environ_vector.erase (it_env);
1508dffb485Schristos     }
1518dffb485Schristos 
1528dffb485Schristos   if (update_unset_list)
1538dffb485Schristos     m_user_unset_env.insert (std::string (var));
1548dffb485Schristos }
1558dffb485Schristos 
1568dffb485Schristos /* See gdbsupport/environ.h.  */
1578dffb485Schristos 
1588dffb485Schristos void
1598dffb485Schristos gdb_environ::unset (const char *var)
1608dffb485Schristos {
1618dffb485Schristos   unset (var, true);
1628dffb485Schristos }
1638dffb485Schristos 
1648dffb485Schristos /* See gdbsupport/environ.h.  */
1658dffb485Schristos 
1668dffb485Schristos char **
1678dffb485Schristos gdb_environ::envp () const
1688dffb485Schristos {
1698dffb485Schristos   return const_cast<char **> (&m_environ_vector[0]);
1708dffb485Schristos }
1718dffb485Schristos 
1728dffb485Schristos /* See gdbsupport/environ.h.  */
1738dffb485Schristos 
1748dffb485Schristos const std::set<std::string> &
1758dffb485Schristos gdb_environ::user_set_env () const
1768dffb485Schristos {
1778dffb485Schristos   return m_user_set_env;
1788dffb485Schristos }
1798dffb485Schristos 
1808dffb485Schristos const std::set<std::string> &
1818dffb485Schristos gdb_environ::user_unset_env () const
1828dffb485Schristos {
1838dffb485Schristos   return m_user_unset_env;
1848dffb485Schristos }
185