This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Adding putenv/setenv functionality to libiberty (for fixincl)


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;
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]