This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Adding putenv/setenv functionality to libiberty (for fixincl)
- To: EGCS Patches <egcs-patches at egcs dot cygnus dot com>
- Subject: Adding putenv/setenv functionality to libiberty (for fixincl)
- From: "Melissa O'Neill" <oneill at cs dot sfu dot ca>
- Date: Sun, 23 May 1999 00:33:12 -0700
- cc: Bruce Korb <fixincludes at autogen dot freeservers dot com>
- References: <199905230622.XAA02517@aldrington.ppp.cs.sfu.ca>
The file gcc/fixinc/fixincl.c relies on the function putenv, which is
not guaranteed to be available on all systems. The putenv function seems
like a good candidate to be included in the libiberty library (certainly
better than adding specialized code to fixincl).
Enclosed is a patch to add putenv (and its cousins setenv and unsetenv)
to libiberty. The code is taken from the glibc-2.0 library, with the
leading `#include's slightly modified, but the remainder of the code
unchanged (although clearenv is removed from setenv.c). I wouldn't have
included setenv/unsetenv were it not for the fact that putenv is
implemented in terms of setenv.
Melissa.
Enc.
--- libiberty/Makefile.in.orig Wed May 19 17:19:01 1999
+++ libiberty/Makefile.in Sat May 22 23:43:49 1999
@@ -119,11 +119,11 @@
bzero.c choose-temp.c clock.c concat.c cplus-dem.c fdmatch.c \
fnmatch.c getcwd.c getopt.c getopt1.c getpagesize.c \
getruntime.c floatformat.c hex.c index.c insque.c memchr.c \
memcmp.c memcpy.c memmove.c memset.c mkstemps.c objalloc.c obstack.c \
- pexecute.c random.c rename.c rindex.c sigsetmask.c spaces.c \
- splay-tree.c strcasecmp.c strncasecmp.c strchr.c strdup.c strerror.c \
- strrchr.c strsignal.c strstr.c strtod.c strtol.c strtoul.c \
+ pexecute.c putenv.c random.c rename.c rindex.c setenv.c sigsetmask.c \
+ spaces.c splay-tree.c strcasecmp.c strncasecmp.c strchr.c strdup.c \
+ strerror.c strrchr.c strsignal.c strstr.c strtod.c strtol.c strtoul.c \
tmpnam.c vasprintf.c vfork.c vfprintf.c vprintf.c vsprintf.c \
waitpid.c xatexit.c xexit.c xmalloc.c xstrdup.c xstrerror.c
# These are always included in the library.
--- libiberty/configure.in.orig Wed May 19 17:19:49 1999
+++ libiberty/configure.in Sun May 23 00:03:11 1999
@@ -129,11 +129,13 @@
funcs="$funcs memcpy"
funcs="$funcs memmove"
funcs="$funcs memset"
funcs="$funcs mkstemps"
+funcs="$funcs putenv"
funcs="$funcs random"
funcs="$funcs rename"
funcs="$funcs rindex"
+funcs="$funcs setenv"
funcs="$funcs sigsetmask"
funcs="$funcs strcasecmp"
funcs="$funcs strchr"
funcs="$funcs strdup"
@@ -160,10 +162,10 @@
# autoheader happy without adding a bunch of text to acconfig.h.
if test "x" = "y"; then
AC_CHECK_FUNCS(asprintf atexit basename bcmp bcopy bzero calloc clock getcwd)
AC_CHECK_FUNCS(getpagesize index insque mkstemps memchr memcmp memcpy memmove)
- AC_CHECK_FUNCS(memset random rename rindex sigsetmask strcasecmp)
- AC_CHECK_FUNCS(strchr strdup strncasecmp strrchr strstr strtod strtol)
+ AC_CHECK_FUNCS(memset putenv random rename rindex sigsetmask strcasecmp)
+ AC_CHECK_FUNCS(setenv strchr strdup strncasecmp strrchr strstr strtod strtol)
AC_CHECK_FUNCS(strtoul tmpnam vasprintf vfprintf vprintf vsprintf waitpid)
AC_DEFINE(HAVE_SYS_ERRLIST)
AC_DEFINE(HAVE_SYS_NERR)
AC_DEFINE(HAVE_SYS_SIGLIST)
--- libiberty/putenv.c.orig Sun May 23 00:00:00 1999
+++ libiberty/putenv.c Sun May 23 00:12:43 1999
@@ -0,0 +1,66 @@
+/* Copyright (C) 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
+ This file based on putenv.c in the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#if defined (_AIX) && !defined (__GNUC__)
+ #pragma alloca
+#endif
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#else
+# ifndef alloca
+# ifdef __GNUC__
+# define alloca __builtin_alloca
+# else
+extern char *alloca ();
+# endif /* __GNUC__ */
+# endif /* alloca */
+#endif /* HAVE_ALLOCA_H */
+
+/* Below this point, it's verbatim code from the glibc-2.0 implementation */
+
+
+/* Put STRING, which is of the form "NAME=VALUE", in the environment. */
+int
+putenv (string)
+ const char *string;
+{
+ const char *const name_end = strchr (string, '=');
+
+ if (name_end)
+ {
+ char *name = alloca (name_end - string + 1);
+ memcpy (name, string, name_end - string);
+ name[name_end - string] = '\0';
+ return setenv (name, name_end + 1, 1);
+ }
+
+ unsetenv (string);
+ return 0;
+}
--- libiberty/setenv.c.orig Sun May 23 00:00:00 1999
+++ libiberty/setenv.c Sun May 23 00:23:09 1999
@@ -0,0 +1,159 @@
+/* Copyright (C) 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file based on setenv.c in the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#if !defined(errno) && !defined(HAVE_ERRNO_DECL)
+extern int errno;
+#endif
+#define __set_errno(ev) ((errno) = (ev))
+
+#if HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#if HAVE_STRING_H
+# include <string.h>
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#define __environ environ
+#ifndef HAVE_ENVIRON_DECL
+extern char **environ;
+#endif
+
+/* LOCK and UNLOCK are defined as no-ops. This makes the libiberty
+ * implementation MT-Unsafe. */
+#define LOCK
+#define UNLOCK
+
+/* Below this point, it's verbatim code from the glibc-2.0 implementation */
+
+/* If this variable is not a null pointer we allocated the current
+ environment. */
+static char **last_environ;
+
+
+int
+setenv (name, value, replace)
+ const char *name;
+ const char *value;
+ int replace;
+{
+ register char **ep;
+ register size_t size;
+ const size_t namelen = strlen (name);
+ const size_t vallen = strlen (value) + 1;
+
+ LOCK;
+
+ size = 0;
+ if (__environ != NULL)
+ for (ep = __environ; *ep != NULL; ++ep)
+ if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
+ break;
+ else
+ ++size;
+
+ if (__environ == NULL || *ep == NULL)
+ {
+ char **new_environ;
+ if (__environ == last_environ && __environ != NULL)
+ /* We allocated this space; we can extend it. */
+ new_environ = (char **) realloc (last_environ,
+ (size + 2) * sizeof (char *));
+ else
+ new_environ = (char **) malloc ((size + 2) * sizeof (char *));
+
+ if (new_environ == NULL)
+ {
+ UNLOCK;
+ return -1;
+ }
+
+ new_environ[size] = malloc (namelen + 1 + vallen);
+ if (new_environ[size] == NULL)
+ {
+ free ((char *) new_environ);
+ __set_errno (ENOMEM);
+ UNLOCK;
+ return -1;
+ }
+
+ if (__environ != last_environ)
+ memcpy ((char *) new_environ, (char *) __environ,
+ size * sizeof (char *));
+
+ memcpy (new_environ[size], name, namelen);
+ new_environ[size][namelen] = '=';
+ memcpy (&new_environ[size][namelen + 1], value, vallen);
+
+ new_environ[size + 1] = NULL;
+
+ last_environ = __environ = new_environ;
+ }
+ else if (replace)
+ {
+ size_t len = strlen (*ep);
+ if (len + 1 < namelen + 1 + vallen)
+ {
+ /* The existing string is too short; malloc a new one. */
+ char *new = malloc (namelen + 1 + vallen);
+ if (new == NULL)
+ {
+ UNLOCK;
+ return -1;
+ }
+ *ep = new;
+ }
+ memcpy (*ep, name, namelen);
+ (*ep)[namelen] = '=';
+ memcpy (&(*ep)[namelen + 1], value, vallen);
+ }
+
+ UNLOCK;
+
+ return 0;
+}
+
+void
+unsetenv (name)
+ const char *name;
+{
+ const size_t len = strlen (name);
+ char **ep;
+
+ LOCK;
+
+ for (ep = __environ; *ep; ++ep)
+ if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
+ {
+ /* Found it. Remove this pointer by moving later ones back. */
+ char **dp = ep;
+ do
+ dp[0] = dp[1];
+ while (*dp++);
+ /* Continue the loop in case NAME appears again. */
+ }
+
+ UNLOCK;
+}