1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-11 14:21:10 +02:00

Make use of Gnulib's `putenv' module.

* libguile/posix.c: Include <stdlib.h> since the putenv(3) declaration
  is there (POSIX and Gnulib).
  (scm_putenv): Rely on Gnulib's `putenv' module.
This commit is contained in:
Ludovic Courtès 2009-05-21 01:17:00 +02:00
parent f240aacb41
commit 3731192f30

View file

@ -21,6 +21,7 @@
# include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
@ -1512,98 +1513,13 @@ SCM_DEFINE (scm_putenv, "putenv", 1, 0, 0,
int rv;
char *c_str = scm_to_locale_string (str);
if (strchr (c_str, '=') == NULL)
{
/* We want no "=" in the argument to mean remove the variable from the
environment, but not all putenv()s understand this, for example
FreeBSD 4.8 doesn't. Getting it happening everywhere is a bit
painful. What unsetenv() exists, we use that, of course.
/* Leave C_STR in the environment. */
Traditionally putenv("NAME") removes a variable, for example that's
what we have to do on Solaris 9 (it doesn't have an unsetenv).
/* Gnulib's `putenv' module honors the semantics described above. */
rv = putenv (c_str);
if (rv < 0)
SCM_SYSERROR;
But on DOS and on that DOS overlay manager thing called W-whatever,
putenv("NAME=") must be used (it too doesn't have an unsetenv).
Supposedly on AIX a putenv("NAME") could cause a segfault, but also
supposedly AIX 5.3 and up has unsetenv() available so should be ok
with the latter there.
For the moment we hard code the DOS putenv("NAME=") style under
__MINGW32__ and do the traditional everywhere else. Such
system-name tests are bad, of course. It'd be possible to use a
configure test when doing a a native build. For example GNU R has
such a test (see R_PUTENV_AS_UNSETENV in
https://svn.r-project.org/R/trunk/m4/R.m4). But when cross
compiling there'd want to be a guess, one probably based on the
system name (ie. mingw or not), thus landing back in basically the
present hard-coded situation. Another possibility for a cross
build would be to try "NAME" then "NAME=" at runtime, if that's not
too much like overkill. */
#if HAVE_UNSETENV
/* when unsetenv() exists then we use it */
unsetenv (c_str);
free (c_str);
#elif defined (__MINGW32__)
/* otherwise putenv("NAME=") on DOS */
int e;
size_t len = strlen (c_str);
char *ptr = scm_malloc (len + 2);
strcpy (ptr, c_str);
strcpy (ptr+len, "=");
rv = putenv (ptr);
e = errno; free (ptr); free (c_str); errno = e;
if (rv < 0)
SCM_SYSERROR;
#else
/* otherwise traditional putenv("NAME") */
rv = putenv (c_str);
if (rv < 0)
SCM_SYSERROR;
#endif
}
else
{
#ifdef __MINGW32__
/* If str is "FOO=", ie. attempting to set an empty string, then
we need to see if it's been successful. On MINGW, "FOO="
means remove FOO from the environment. As a workaround, we
set "FOO= ", ie. a space, and then modify the string returned
by getenv. It's not enough just to modify the string we set,
because MINGW putenv copies it. */
{
size_t len = strlen (c_str);
if (c_str[len-1] == '=')
{
char *ptr = scm_malloc (len+2);
strcpy (ptr, c_str);
strcpy (ptr+len, " ");
rv = putenv (ptr);
if (rv < 0)
{
int eno = errno;
free (c_str);
errno = eno;
SCM_SYSERROR;
}
/* truncate to just the name */
c_str[len-1] = '\0';
ptr = getenv (c_str);
if (ptr)
ptr[0] = '\0';
return SCM_UNSPECIFIED;
}
}
#endif /* __MINGW32__ */
/* Leave c_str in the environment. */
rv = putenv (c_str);
if (rv < 0)
SCM_SYSERROR;
}
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME