119370Spst/* environ.c -- library for manipulating environments for GNU. 219370Spst 3130803Smarcel Copyright 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 2000, 4130803Smarcel 2003 Free Software Foundation, Inc. 5130803Smarcel 698944Sobrien This program is free software; you can redistribute it and/or modify 798944Sobrien it under the terms of the GNU General Public License as published by 898944Sobrien the Free Software Foundation; either version 2 of the License, or 998944Sobrien (at your option) any later version. 1019370Spst 1198944Sobrien This program is distributed in the hope that it will be useful, 1298944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1398944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1498944Sobrien GNU General Public License for more details. 1519370Spst 1698944Sobrien You should have received a copy of the GNU General Public License 1798944Sobrien along with this program; if not, write to the Free Software 1898944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 1998944Sobrien Boston, MA 02111-1307, USA. */ 2019370Spst 2119370Spst#define min(a, b) ((a) < (b) ? (a) : (b)) 2219370Spst#define max(a, b) ((a) > (b) ? (a) : (b)) 2319370Spst 2419370Spst#include "defs.h" 2519370Spst#include "environ.h" 2619370Spst#include "gdb_string.h" 2798944Sobrien 2819370Spst 2919370Spst/* Return a new environment object. */ 3019370Spst 3119370Spststruct environ * 3298944Sobrienmake_environ (void) 3319370Spst{ 34130803Smarcel struct environ *e; 3519370Spst 3619370Spst e = (struct environ *) xmalloc (sizeof (struct environ)); 3719370Spst 3819370Spst e->allocated = 10; 3919370Spst e->vector = (char **) xmalloc ((e->allocated + 1) * sizeof (char *)); 4019370Spst e->vector[0] = 0; 4119370Spst return e; 4219370Spst} 4319370Spst 4419370Spst/* Free an environment and all the strings in it. */ 4519370Spst 4619370Spstvoid 47130803Smarcelfree_environ (struct environ *e) 4819370Spst{ 49130803Smarcel char **vector = e->vector; 5019370Spst 5119370Spst while (*vector) 5298944Sobrien xfree (*vector++); 5319370Spst 5498944Sobrien xfree (e); 5519370Spst} 5619370Spst 5719370Spst/* Copy the environment given to this process into E. 5819370Spst Also copies all the strings in it, so we can be sure 5919370Spst that all strings in these environments are safe to free. */ 6019370Spst 6119370Spstvoid 62130803Smarcelinit_environ (struct environ *e) 6319370Spst{ 6419370Spst extern char **environ; 65130803Smarcel int i; 6619370Spst 6719370Spst if (environ == NULL) 6819370Spst return; 6919370Spst 7098944Sobrien for (i = 0; environ[i]; i++) /*EMPTY */ ; 7119370Spst 7219370Spst if (e->allocated < i) 7319370Spst { 7419370Spst e->allocated = max (i, e->allocated + 10); 7598944Sobrien e->vector = (char **) xrealloc ((char *) e->vector, 7619370Spst (e->allocated + 1) * sizeof (char *)); 7719370Spst } 7819370Spst 7919370Spst memcpy (e->vector, environ, (i + 1) * sizeof (char *)); 8019370Spst 8119370Spst while (--i >= 0) 8219370Spst { 83130803Smarcel int len = strlen (e->vector[i]); 84130803Smarcel char *new = (char *) xmalloc (len + 1); 8519370Spst memcpy (new, e->vector[i], len + 1); 8619370Spst e->vector[i] = new; 8719370Spst } 8819370Spst} 8919370Spst 9019370Spst/* Return the vector of environment E. 9119370Spst This is used to get something to pass to execve. */ 9219370Spst 9319370Spstchar ** 9498944Sobrienenviron_vector (struct environ *e) 9519370Spst{ 9619370Spst return e->vector; 9719370Spst} 9819370Spst 9919370Spst/* Return the value in environment E of variable VAR. */ 10019370Spst 10119370Spstchar * 10298944Sobrienget_in_environ (const struct environ *e, const char *var) 10319370Spst{ 104130803Smarcel int len = strlen (var); 105130803Smarcel char **vector = e->vector; 106130803Smarcel char *s; 10719370Spst 10819370Spst for (; (s = *vector) != NULL; vector++) 109130803Smarcel if (strncmp (s, var, len) == 0 && s[len] == '=') 11019370Spst return &s[len + 1]; 11119370Spst 11219370Spst return 0; 11319370Spst} 11419370Spst 11519370Spst/* Store the value in E of VAR as VALUE. */ 11619370Spst 11719370Spstvoid 11898944Sobrienset_in_environ (struct environ *e, const char *var, const char *value) 11919370Spst{ 120130803Smarcel int i; 121130803Smarcel int len = strlen (var); 122130803Smarcel char **vector = e->vector; 123130803Smarcel char *s; 12419370Spst 12519370Spst for (i = 0; (s = vector[i]) != NULL; i++) 126130803Smarcel if (strncmp (s, var, len) == 0 && s[len] == '=') 12719370Spst break; 12819370Spst 12919370Spst if (s == 0) 13019370Spst { 13119370Spst if (i == e->allocated) 13219370Spst { 13319370Spst e->allocated += 10; 13498944Sobrien vector = (char **) xrealloc ((char *) vector, 13519370Spst (e->allocated + 1) * sizeof (char *)); 13619370Spst e->vector = vector; 13719370Spst } 13819370Spst vector[i + 1] = 0; 13919370Spst } 14019370Spst else 14198944Sobrien xfree (s); 14219370Spst 14319370Spst s = (char *) xmalloc (len + strlen (value) + 2); 14419370Spst strcpy (s, var); 14519370Spst strcat (s, "="); 14619370Spst strcat (s, value); 14719370Spst vector[i] = s; 14819370Spst 14919370Spst /* This used to handle setting the PATH and GNUTARGET variables 15019370Spst specially. The latter has been replaced by "set gnutarget" 15119370Spst (which has worked since GDB 4.11). The former affects searching 15219370Spst the PATH to find SHELL, and searching the PATH to find the 15319370Spst argument of "symbol-file" or "exec-file". Maybe we should have 15419370Spst some kind of "set exec-path" for that. But in any event, having 15519370Spst "set env" affect anything besides the inferior is a bad idea. 15619370Spst What if we want to change the environment we pass to the program 15719370Spst without afecting GDB's behavior? */ 15819370Spst 15919370Spst return; 16019370Spst} 16119370Spst 16219370Spst/* Remove the setting for variable VAR from environment E. */ 16319370Spst 16419370Spstvoid 16598944Sobrienunset_in_environ (struct environ *e, char *var) 16619370Spst{ 167130803Smarcel int len = strlen (var); 168130803Smarcel char **vector = e->vector; 169130803Smarcel char *s; 17019370Spst 17119370Spst for (; (s = *vector) != NULL; vector++) 17219370Spst { 173130803Smarcel if (DEPRECATED_STREQN (s, var, len) && s[len] == '=') 17419370Spst { 17598944Sobrien xfree (s); 17619370Spst /* Walk through the vector, shuffling args down by one, including 17719370Spst the NULL terminator. Can't use memcpy() here since the regions 17819370Spst overlap, and memmove() might not be available. */ 17919370Spst while ((vector[0] = vector[1]) != NULL) 18019370Spst { 18119370Spst vector++; 18219370Spst } 18319370Spst break; 18419370Spst } 18519370Spst } 18619370Spst} 187