GDB (API)
|
00001 /* environ.c -- library for manipulating environments for GNU. 00002 00003 Copyright (C) 1986-2013 Free Software Foundation, Inc. 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 3 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00017 00018 #define min(a, b) ((a) < (b) ? (a) : (b)) 00019 #define max(a, b) ((a) > (b) ? (a) : (b)) 00020 00021 #include "defs.h" 00022 #include "environ.h" 00023 #include "gdb_string.h" 00024 00025 00026 /* Return a new environment object. */ 00027 00028 struct gdb_environ * 00029 make_environ (void) 00030 { 00031 struct gdb_environ *e; 00032 00033 e = (struct gdb_environ *) xmalloc (sizeof (struct gdb_environ)); 00034 00035 e->allocated = 10; 00036 e->vector = (char **) xmalloc ((e->allocated + 1) * sizeof (char *)); 00037 e->vector[0] = 0; 00038 return e; 00039 } 00040 00041 /* Free an environment and all the strings in it. */ 00042 00043 void 00044 free_environ (struct gdb_environ *e) 00045 { 00046 char **vector = e->vector; 00047 00048 while (*vector) 00049 xfree (*vector++); 00050 00051 xfree (e->vector); 00052 xfree (e); 00053 } 00054 00055 /* Copy the environment given to this process into E. 00056 Also copies all the strings in it, so we can be sure 00057 that all strings in these environments are safe to free. */ 00058 00059 void 00060 init_environ (struct gdb_environ *e) 00061 { 00062 extern char **environ; 00063 int i; 00064 00065 if (environ == NULL) 00066 return; 00067 00068 for (i = 0; environ[i]; i++) /*EMPTY */ ; 00069 00070 if (e->allocated < i) 00071 { 00072 e->allocated = max (i, e->allocated + 10); 00073 e->vector = (char **) xrealloc ((char *) e->vector, 00074 (e->allocated + 1) * sizeof (char *)); 00075 } 00076 00077 memcpy (e->vector, environ, (i + 1) * sizeof (char *)); 00078 00079 while (--i >= 0) 00080 { 00081 int len = strlen (e->vector[i]); 00082 char *new = (char *) xmalloc (len + 1); 00083 00084 memcpy (new, e->vector[i], len + 1); 00085 e->vector[i] = new; 00086 } 00087 } 00088 00089 /* Return the vector of environment E. 00090 This is used to get something to pass to execve. */ 00091 00092 char ** 00093 environ_vector (struct gdb_environ *e) 00094 { 00095 return e->vector; 00096 } 00097 00098 /* Return the value in environment E of variable VAR. */ 00099 00100 char * 00101 get_in_environ (const struct gdb_environ *e, const char *var) 00102 { 00103 int len = strlen (var); 00104 char **vector = e->vector; 00105 char *s; 00106 00107 for (; (s = *vector) != NULL; vector++) 00108 if (strncmp (s, var, len) == 0 && s[len] == '=') 00109 return &s[len + 1]; 00110 00111 return 0; 00112 } 00113 00114 /* Store the value in E of VAR as VALUE. */ 00115 00116 void 00117 set_in_environ (struct gdb_environ *e, const char *var, const char *value) 00118 { 00119 int i; 00120 int len = strlen (var); 00121 char **vector = e->vector; 00122 char *s; 00123 00124 for (i = 0; (s = vector[i]) != NULL; i++) 00125 if (strncmp (s, var, len) == 0 && s[len] == '=') 00126 break; 00127 00128 if (s == 0) 00129 { 00130 if (i == e->allocated) 00131 { 00132 e->allocated += 10; 00133 vector = (char **) xrealloc ((char *) vector, 00134 (e->allocated + 1) * sizeof (char *)); 00135 e->vector = vector; 00136 } 00137 vector[i + 1] = 0; 00138 } 00139 else 00140 xfree (s); 00141 00142 s = (char *) xmalloc (len + strlen (value) + 2); 00143 strcpy (s, var); 00144 strcat (s, "="); 00145 strcat (s, value); 00146 vector[i] = s; 00147 00148 /* This used to handle setting the PATH and GNUTARGET variables 00149 specially. The latter has been replaced by "set gnutarget" 00150 (which has worked since GDB 4.11). The former affects searching 00151 the PATH to find SHELL, and searching the PATH to find the 00152 argument of "symbol-file" or "exec-file". Maybe we should have 00153 some kind of "set exec-path" for that. But in any event, having 00154 "set env" affect anything besides the inferior is a bad idea. 00155 What if we want to change the environment we pass to the program 00156 without afecting GDB's behavior? */ 00157 00158 return; 00159 } 00160 00161 /* Remove the setting for variable VAR from environment E. */ 00162 00163 void 00164 unset_in_environ (struct gdb_environ *e, char *var) 00165 { 00166 int len = strlen (var); 00167 char **vector = e->vector; 00168 char *s; 00169 00170 for (; (s = *vector) != NULL; vector++) 00171 { 00172 if (strncmp (s, var, len) == 0 && s[len] == '=') 00173 { 00174 xfree (s); 00175 /* Walk through the vector, shuffling args down by one, including 00176 the NULL terminator. Can't use memcpy() here since the regions 00177 overlap, and memmove() might not be available. */ 00178 while ((vector[0] = vector[1]) != NULL) 00179 { 00180 vector++; 00181 } 00182 break; 00183 } 00184 } 00185 }