environ.c revision 98944
119370Spst/* environ.c -- library for manipulating environments for GNU. 298944Sobrien Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 2000 398944Sobrien Free Software Foundation, Inc. 419370Spst 598944Sobrien This program is free software; you can redistribute it and/or modify 698944Sobrien it under the terms of the GNU General Public License as published by 798944Sobrien the Free Software Foundation; either version 2 of the License, or 898944Sobrien (at your option) any later version. 919370Spst 1098944Sobrien This program is distributed in the hope that it will be useful, 1198944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1298944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1398944Sobrien GNU General Public License for more details. 1419370Spst 1598944Sobrien You should have received a copy of the GNU General Public License 1698944Sobrien along with this program; if not, write to the Free Software 1798944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 1898944Sobrien Boston, MA 02111-1307, USA. */ 1919370Spst 2019370Spst#define min(a, b) ((a) < (b) ? (a) : (b)) 2119370Spst#define max(a, b) ((a) > (b) ? (a) : (b)) 2219370Spst 2319370Spst#include "defs.h" 2419370Spst#include "environ.h" 2519370Spst#include "gdb_string.h" 2698944Sobrien 2719370Spst 2819370Spst/* Return a new environment object. */ 2919370Spst 3019370Spststruct environ * 3198944Sobrienmake_environ (void) 3219370Spst{ 3319370Spst register struct environ *e; 3419370Spst 3519370Spst e = (struct environ *) xmalloc (sizeof (struct environ)); 3619370Spst 3719370Spst e->allocated = 10; 3819370Spst e->vector = (char **) xmalloc ((e->allocated + 1) * sizeof (char *)); 3919370Spst e->vector[0] = 0; 4019370Spst return e; 4119370Spst} 4219370Spst 4319370Spst/* Free an environment and all the strings in it. */ 4419370Spst 4519370Spstvoid 4698944Sobrienfree_environ (register struct environ *e) 4719370Spst{ 4819370Spst register char **vector = e->vector; 4919370Spst 5019370Spst while (*vector) 5198944Sobrien xfree (*vector++); 5219370Spst 5398944Sobrien xfree (e); 5419370Spst} 5519370Spst 5619370Spst/* Copy the environment given to this process into E. 5719370Spst Also copies all the strings in it, so we can be sure 5819370Spst that all strings in these environments are safe to free. */ 5919370Spst 6019370Spstvoid 6198944Sobrieninit_environ (register struct environ *e) 6219370Spst{ 6319370Spst extern char **environ; 6419370Spst register int i; 6519370Spst 6619370Spst if (environ == NULL) 6719370Spst return; 6819370Spst 6998944Sobrien for (i = 0; environ[i]; i++) /*EMPTY */ ; 7019370Spst 7119370Spst if (e->allocated < i) 7219370Spst { 7319370Spst e->allocated = max (i, e->allocated + 10); 7498944Sobrien e->vector = (char **) xrealloc ((char *) e->vector, 7519370Spst (e->allocated + 1) * sizeof (char *)); 7619370Spst } 7719370Spst 7819370Spst memcpy (e->vector, environ, (i + 1) * sizeof (char *)); 7919370Spst 8019370Spst while (--i >= 0) 8119370Spst { 8219370Spst register int len = strlen (e->vector[i]); 8319370Spst register char *new = (char *) xmalloc (len + 1); 8419370Spst memcpy (new, e->vector[i], len + 1); 8519370Spst e->vector[i] = new; 8619370Spst } 8719370Spst} 8819370Spst 8919370Spst/* Return the vector of environment E. 9019370Spst This is used to get something to pass to execve. */ 9119370Spst 9219370Spstchar ** 9398944Sobrienenviron_vector (struct environ *e) 9419370Spst{ 9519370Spst return e->vector; 9619370Spst} 9719370Spst 9819370Spst/* Return the value in environment E of variable VAR. */ 9919370Spst 10019370Spstchar * 10198944Sobrienget_in_environ (const struct environ *e, const char *var) 10219370Spst{ 10319370Spst register int len = strlen (var); 10419370Spst register char **vector = e->vector; 10519370Spst register char *s; 10619370Spst 10719370Spst for (; (s = *vector) != NULL; vector++) 10819370Spst if (STREQN (s, var, len) && s[len] == '=') 10919370Spst return &s[len + 1]; 11019370Spst 11119370Spst return 0; 11219370Spst} 11319370Spst 11419370Spst/* Store the value in E of VAR as VALUE. */ 11519370Spst 11619370Spstvoid 11798944Sobrienset_in_environ (struct environ *e, const char *var, const char *value) 11819370Spst{ 11919370Spst register int i; 12019370Spst register int len = strlen (var); 12119370Spst register char **vector = e->vector; 12219370Spst register char *s; 12319370Spst 12419370Spst for (i = 0; (s = vector[i]) != NULL; i++) 12519370Spst if (STREQN (s, var, len) && s[len] == '=') 12619370Spst break; 12719370Spst 12819370Spst if (s == 0) 12919370Spst { 13019370Spst if (i == e->allocated) 13119370Spst { 13219370Spst e->allocated += 10; 13398944Sobrien vector = (char **) xrealloc ((char *) vector, 13419370Spst (e->allocated + 1) * sizeof (char *)); 13519370Spst e->vector = vector; 13619370Spst } 13719370Spst vector[i + 1] = 0; 13819370Spst } 13919370Spst else 14098944Sobrien xfree (s); 14119370Spst 14219370Spst s = (char *) xmalloc (len + strlen (value) + 2); 14319370Spst strcpy (s, var); 14419370Spst strcat (s, "="); 14519370Spst strcat (s, value); 14619370Spst vector[i] = s; 14719370Spst 14819370Spst /* This used to handle setting the PATH and GNUTARGET variables 14919370Spst specially. The latter has been replaced by "set gnutarget" 15019370Spst (which has worked since GDB 4.11). The former affects searching 15119370Spst the PATH to find SHELL, and searching the PATH to find the 15219370Spst argument of "symbol-file" or "exec-file". Maybe we should have 15319370Spst some kind of "set exec-path" for that. But in any event, having 15419370Spst "set env" affect anything besides the inferior is a bad idea. 15519370Spst What if we want to change the environment we pass to the program 15619370Spst without afecting GDB's behavior? */ 15719370Spst 15819370Spst return; 15919370Spst} 16019370Spst 16119370Spst/* Remove the setting for variable VAR from environment E. */ 16219370Spst 16319370Spstvoid 16498944Sobrienunset_in_environ (struct environ *e, char *var) 16519370Spst{ 16619370Spst register int len = strlen (var); 16719370Spst register char **vector = e->vector; 16819370Spst register char *s; 16919370Spst 17019370Spst for (; (s = *vector) != NULL; vector++) 17119370Spst { 17219370Spst if (STREQN (s, var, len) && s[len] == '=') 17319370Spst { 17498944Sobrien xfree (s); 17519370Spst /* Walk through the vector, shuffling args down by one, including 17619370Spst the NULL terminator. Can't use memcpy() here since the regions 17719370Spst overlap, and memmove() might not be available. */ 17819370Spst while ((vector[0] = vector[1]) != NULL) 17919370Spst { 18019370Spst vector++; 18119370Spst } 18219370Spst break; 18319370Spst } 18419370Spst } 18519370Spst} 186