setenv.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. /* Copyright (C) 1992, 1995-2003, 2005-2010 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. #if !_LIBC
  14. # include <config.h>
  15. #endif
  16. /* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
  17. optimizes away the name == NULL test below. */
  18. #define _GL_ARG_NONNULL(params)
  19. #include <alloca.h>
  20. /* Specification. */
  21. #include <stdlib.h>
  22. #include <errno.h>
  23. #ifndef __set_errno
  24. # define __set_errno(ev) ((errno) = (ev))
  25. #endif
  26. #include <string.h>
  27. #if _LIBC || HAVE_UNISTD_H
  28. # include <unistd.h>
  29. #endif
  30. #if !_LIBC
  31. # include "malloca.h"
  32. #endif
  33. #if _LIBC || !HAVE_SETENV
  34. #if !_LIBC
  35. # define __environ environ
  36. #endif
  37. #if _LIBC
  38. /* This lock protects against simultaneous modifications of `environ'. */
  39. # include <bits/libc-lock.h>
  40. __libc_lock_define_initialized (static, envlock)
  41. # define LOCK __libc_lock_lock (envlock)
  42. # define UNLOCK __libc_lock_unlock (envlock)
  43. #else
  44. # define LOCK
  45. # define UNLOCK
  46. #endif
  47. /* In the GNU C library we must keep the namespace clean. */
  48. #ifdef _LIBC
  49. # define setenv __setenv
  50. # define clearenv __clearenv
  51. # define tfind __tfind
  52. # define tsearch __tsearch
  53. #else
  54. /* Use the system functions, not the gnulib overrides in this file. */
  55. # undef malloc
  56. # undef realloc
  57. #endif
  58. /* In the GNU C library implementation we try to be more clever and
  59. allow arbitrarily many changes of the environment given that the used
  60. values are from a small set. Outside glibc this will eat up all
  61. memory after a while. */
  62. #if defined _LIBC || (defined HAVE_SEARCH_H && defined HAVE_TSEARCH \
  63. && defined __GNUC__)
  64. # define USE_TSEARCH 1
  65. # include <search.h>
  66. typedef int (*compar_fn_t) (const void *, const void *);
  67. /* This is a pointer to the root of the search tree with the known
  68. values. */
  69. static void *known_values;
  70. # define KNOWN_VALUE(Str) \
  71. ({ \
  72. void *value = tfind (Str, &known_values, (compar_fn_t) strcmp); \
  73. value != NULL ? *(char **) value : NULL; \
  74. })
  75. # define STORE_VALUE(Str) \
  76. tsearch (Str, &known_values, (compar_fn_t) strcmp)
  77. #else
  78. # undef USE_TSEARCH
  79. # define KNOWN_VALUE(Str) NULL
  80. # define STORE_VALUE(Str) do { } while (0)
  81. #endif
  82. /* If this variable is not a null pointer we allocated the current
  83. environment. */
  84. static char **last_environ;
  85. /* This function is used by `setenv' and `putenv'. The difference between
  86. the two functions is that for the former must create a new string which
  87. is then placed in the environment, while the argument of `putenv'
  88. must be used directly. This is all complicated by the fact that we try
  89. to reuse values once generated for a `setenv' call since we can never
  90. free the strings. */
  91. int
  92. __add_to_environ (const char *name, const char *value, const char *combined,
  93. int replace)
  94. {
  95. char **ep;
  96. size_t size;
  97. const size_t namelen = strlen (name);
  98. const size_t vallen = value != NULL ? strlen (value) + 1 : 0;
  99. LOCK;
  100. /* We have to get the pointer now that we have the lock and not earlier
  101. since another thread might have created a new environment. */
  102. ep = __environ;
  103. size = 0;
  104. if (ep != NULL)
  105. {
  106. for (; *ep != NULL; ++ep)
  107. if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
  108. break;
  109. else
  110. ++size;
  111. }
  112. if (ep == NULL || *ep == NULL)
  113. {
  114. char **new_environ;
  115. #ifdef USE_TSEARCH
  116. char *new_value;
  117. #endif
  118. /* We allocated this space; we can extend it. */
  119. new_environ =
  120. (char **) (last_environ == NULL
  121. ? malloc ((size + 2) * sizeof (char *))
  122. : realloc (last_environ, (size + 2) * sizeof (char *)));
  123. if (new_environ == NULL)
  124. {
  125. /* It's easier to set errno to ENOMEM than to rely on the
  126. 'malloc-posix' and 'realloc-posix' gnulib modules. */
  127. __set_errno (ENOMEM);
  128. UNLOCK;
  129. return -1;
  130. }
  131. /* If the whole entry is given add it. */
  132. if (combined != NULL)
  133. /* We must not add the string to the search tree since it belongs
  134. to the user. */
  135. new_environ[size] = (char *) combined;
  136. else
  137. {
  138. /* See whether the value is already known. */
  139. #ifdef USE_TSEARCH
  140. # ifdef _LIBC
  141. new_value = (char *) alloca (namelen + 1 + vallen);
  142. __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
  143. value, vallen);
  144. # else
  145. new_value = (char *) malloca (namelen + 1 + vallen);
  146. if (new_value == NULL)
  147. {
  148. __set_errno (ENOMEM);
  149. UNLOCK;
  150. return -1;
  151. }
  152. memcpy (new_value, name, namelen);
  153. new_value[namelen] = '=';
  154. memcpy (&new_value[namelen + 1], value, vallen);
  155. # endif
  156. new_environ[size] = KNOWN_VALUE (new_value);
  157. if (new_environ[size] == NULL)
  158. #endif
  159. {
  160. new_environ[size] = (char *) malloc (namelen + 1 + vallen);
  161. if (new_environ[size] == NULL)
  162. {
  163. #if defined USE_TSEARCH && !defined _LIBC
  164. freea (new_value);
  165. #endif
  166. __set_errno (ENOMEM);
  167. UNLOCK;
  168. return -1;
  169. }
  170. #ifdef USE_TSEARCH
  171. memcpy (new_environ[size], new_value, namelen + 1 + vallen);
  172. #else
  173. memcpy (new_environ[size], name, namelen);
  174. new_environ[size][namelen] = '=';
  175. memcpy (&new_environ[size][namelen + 1], value, vallen);
  176. #endif
  177. /* And save the value now. We cannot do this when we remove
  178. the string since then we cannot decide whether it is a
  179. user string or not. */
  180. STORE_VALUE (new_environ[size]);
  181. }
  182. #if defined USE_TSEARCH && !defined _LIBC
  183. freea (new_value);
  184. #endif
  185. }
  186. if (__environ != last_environ)
  187. memcpy ((char *) new_environ, (char *) __environ,
  188. size * sizeof (char *));
  189. new_environ[size + 1] = NULL;
  190. last_environ = __environ = new_environ;
  191. }
  192. else if (replace)
  193. {
  194. char *np;
  195. /* Use the user string if given. */
  196. if (combined != NULL)
  197. np = (char *) combined;
  198. else
  199. {
  200. #ifdef USE_TSEARCH
  201. char *new_value;
  202. # ifdef _LIBC
  203. new_value = alloca (namelen + 1 + vallen);
  204. __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
  205. value, vallen);
  206. # else
  207. new_value = malloca (namelen + 1 + vallen);
  208. if (new_value == NULL)
  209. {
  210. __set_errno (ENOMEM);
  211. UNLOCK;
  212. return -1;
  213. }
  214. memcpy (new_value, name, namelen);
  215. new_value[namelen] = '=';
  216. memcpy (&new_value[namelen + 1], value, vallen);
  217. # endif
  218. np = KNOWN_VALUE (new_value);
  219. if (np == NULL)
  220. #endif
  221. {
  222. np = (char *) malloc (namelen + 1 + vallen);
  223. if (np == NULL)
  224. {
  225. #if defined USE_TSEARCH && !defined _LIBC
  226. freea (new_value);
  227. #endif
  228. __set_errno (ENOMEM);
  229. UNLOCK;
  230. return -1;
  231. }
  232. #ifdef USE_TSEARCH
  233. memcpy (np, new_value, namelen + 1 + vallen);
  234. #else
  235. memcpy (np, name, namelen);
  236. np[namelen] = '=';
  237. memcpy (&np[namelen + 1], value, vallen);
  238. #endif
  239. /* And remember the value. */
  240. STORE_VALUE (np);
  241. }
  242. #if defined USE_TSEARCH && !defined _LIBC
  243. freea (new_value);
  244. #endif
  245. }
  246. *ep = np;
  247. }
  248. UNLOCK;
  249. return 0;
  250. }
  251. int
  252. setenv (const char *name, const char *value, int replace)
  253. {
  254. if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
  255. {
  256. __set_errno (EINVAL);
  257. return -1;
  258. }
  259. return __add_to_environ (name, value, NULL, replace);
  260. }
  261. /* The `clearenv' was planned to be added to POSIX.1 but probably
  262. never made it. Nevertheless the POSIX.9 standard (POSIX bindings
  263. for Fortran 77) requires this function. */
  264. int
  265. clearenv (void)
  266. {
  267. LOCK;
  268. if (__environ == last_environ && __environ != NULL)
  269. {
  270. /* We allocated this environment so we can free it. */
  271. free (__environ);
  272. last_environ = NULL;
  273. }
  274. /* Clear the environment pointer removes the whole environment. */
  275. __environ = NULL;
  276. UNLOCK;
  277. return 0;
  278. }
  279. #ifdef _LIBC
  280. static void
  281. free_mem (void)
  282. {
  283. /* Remove all traces. */
  284. clearenv ();
  285. /* Now remove the search tree. */
  286. __tdestroy (known_values, free);
  287. known_values = NULL;
  288. }
  289. text_set_element (__libc_subfreeres, free_mem);
  290. # undef setenv
  291. # undef clearenv
  292. weak_alias (__setenv, setenv)
  293. weak_alias (__clearenv, clearenv)
  294. #endif
  295. #endif /* _LIBC || !HAVE_SETENV */
  296. /* The rest of this file is called into use when replacing an existing
  297. but buggy setenv. Known bugs include failure to diagnose invalid
  298. name, and consuming a leading '=' from value. */
  299. #if HAVE_SETENV
  300. # undef setenv
  301. # define STREQ(a, b) (strcmp (a, b) == 0)
  302. int
  303. rpl_setenv (const char *name, const char *value, int replace)
  304. {
  305. int result;
  306. if (!name || !*name || strchr (name, '='))
  307. {
  308. errno = EINVAL;
  309. return -1;
  310. }
  311. /* Call the real setenv even if replace is 0, in case implementation
  312. has underlying data to update, such as when environ changes. */
  313. result = setenv (name, value, replace);
  314. if (result == 0 && replace && *value == '=')
  315. {
  316. char *tmp = getenv (name);
  317. if (!STREQ (tmp, value))
  318. {
  319. int saved_errno;
  320. size_t len = strlen (value);
  321. tmp = malloca (len + 2);
  322. /* Since leading '=' is eaten, double it up. */
  323. *tmp = '=';
  324. memcpy (tmp + 1, value, len + 1);
  325. result = setenv (name, tmp, replace);
  326. saved_errno = errno;
  327. freea (tmp);
  328. errno = saved_errno;
  329. }
  330. }
  331. return result;
  332. }
  333. #endif /* HAVE_SETENV */