mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-12 23:00:22 +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:
parent
f240aacb41
commit
3731192f30
1 changed files with 6 additions and 90 deletions
|
@ -21,6 +21,7 @@
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
@ -1512,98 +1513,13 @@ SCM_DEFINE (scm_putenv, "putenv", 1, 0, 0,
|
||||||
int rv;
|
int rv;
|
||||||
char *c_str = scm_to_locale_string (str);
|
char *c_str = scm_to_locale_string (str);
|
||||||
|
|
||||||
if (strchr (c_str, '=') == NULL)
|
/* Leave C_STR in the environment. */
|
||||||
{
|
|
||||||
/* 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.
|
|
||||||
|
|
||||||
Traditionally putenv("NAME") removes a variable, for example that's
|
/* Gnulib's `putenv' module honors the semantics described above. */
|
||||||
what we have to do on Solaris 9 (it doesn't have an unsetenv).
|
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;
|
return SCM_UNSPECIFIED;
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue