www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2004/08/10/10:40:29

X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f
Date: Tue, 10 Aug 2004 13:59:24 +0300 (EET DST)
From: Esa A E Peuha <peuha AT cc DOT helsinki DOT fi>
Sender: peuha AT sirppi DOT helsinki DOT fi
To: djgpp-workers AT delorie DOT com
Subject: Fix for environ pollution
Message-ID: <Pine.OSF.4.58.0408101319280.24206@sirppi.helsinki.fi>
MIME-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com

As Brian Ingals noticed, the variable environ currently pollutes the
namespace.  The solution is obvious: change all references to environ
to _environ in the library, and move its declaration from crt1.c to
djgpp.djl which can then provide environ to those programs that expect
it.  Here's a patch to do it:

? include/complex.h
? src/libc/c99/complex
? src/mkdoc/mkdoc.cc.new
Index: lib/djgpp.djl
===================================================================
RCS file: /cvs/djgpp/djgpp/lib/djgpp.djl,v
retrieving revision 1.8
diff -u -r1.8 djgpp.djl
--- lib/djgpp.djl	22 Dec 2002 18:44:42 -0000	1.8
+++ lib/djgpp.djl	10 Aug 2004 10:48:21 -0000
@@ -19,6 +19,9 @@
     djgpp_first_dtor = . ;
     *(.dtor)
     djgpp_last_dtor = . ;
+    __environ = . ;
+    PROVIDE(_environ = .)
+    LONG(0)
     *(.data)
     *(.data.*)
     *(.gnu.linkonce.d*)
Index: src/libc/ansi/stdlib/getenv.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdlib/getenv.c,v
retrieving revision 1.1
diff -u -r1.1 getenv.c
--- src/libc/ansi/stdlib/getenv.c	25 Nov 1995 03:21:18 -0000	1.1
+++ src/libc/ansi/stdlib/getenv.c	10 Aug 2004 10:48:21 -0000
@@ -2,19 +2,19 @@
 #include <stdlib.h>
 #include <string.h>

-extern char **environ;
+extern char **_environ;

 char *
 getenv(const char *name)
 {
   int i;

-  if (environ == 0)
+  if (_environ == 0)
     return 0;

-  for (i=0; environ[i]; i++)
+  for (i=0; _environ[i]; i++)
   {
-    char *ep = environ[i];
+    char *ep = _environ[i];
     const char *np = name;
     while (*ep && *np && *ep == *np && *np != '=')
       ep++, np++;
Index: src/libc/ansi/stdlib/system.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdlib/system.c,v
retrieving revision 1.10
diff -u -r1.10 system.c
--- src/libc/ansi/stdlib/system.c	17 Oct 2002 23:00:24 -0000	1.10
+++ src/libc/ansi/stdlib/system.c	10 Aug 2004 10:48:22 -0000
@@ -23,7 +23,7 @@
 #include <libc/unconst.h>
 #include <libc/file.h> /* for fileno() */

-extern char **environ;
+extern char **_environ;
 #define alloca __builtin_alloca

 typedef enum {
@@ -92,7 +92,7 @@
   {
     /* Special case: zero or empty command line means just invoke
        the command interpreter and let the user type ``exit''.  */
-    return _dos_exec (shell, "", environ, 0);
+    return _dos_exec (shell, "", _environ, 0);
   }
   else if (_is_dos_shell (shell))
   {
@@ -170,11 +170,11 @@
 	  return emiterror ("Command line too long.", 0);
 	}
 	else
-	  return _dos_exec(shell, cmd_tail, environ, cmdline_var);
+	  return _dos_exec(shell, cmd_tail, _environ, cmdline_var);
       }
     }
     else
-      return _dos_exec (shell, cmd_tail, environ, 0);
+      return _dos_exec (shell, cmd_tail, _environ, 0);
   }
   else
   {
@@ -209,7 +209,7 @@
       fclose (respf);
       strcpy (cmd_tail, " ");
       strcat (cmd_tail, atfile);
-      retval = _dos_exec (shell, cmd_tail, environ, 0);
+      retval = _dos_exec (shell, cmd_tail, _environ, 0);
       remove (atfile);
       return retval;
     }
@@ -235,7 +235,7 @@
   char found_at[FILENAME_MAX];
   int e = errno;

-  if (__dosexec_find_on_path (prog, environ, found_at))
+  if (__dosexec_find_on_path (prog, _environ, found_at))
   {
     char **pargv, **this_arg;
     int    pargc = 2;		/* PROG is one, terminating 0 is another */
@@ -250,7 +250,7 @@
 	return emiterror ("Command line too long.", 0);
       }

-      return _dos_exec (found_at, args, environ, 0);
+      return _dos_exec (found_at, args, _environ, 0);
     }

     /* Pass 1: how many arguments do we have?  */
@@ -282,7 +282,7 @@
     }
     *this_arg = 0;

-    return __spawnve(P_WAIT, found_at, pargv, (char * const *)environ);
+    return __spawnve(P_WAIT, found_at, pargv, (char * const *)_environ);
   }
   else
   {
Index: src/libc/compat/stdlib/putenv.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/compat/stdlib/putenv.c,v
retrieving revision 1.4
diff -u -r1.4 putenv.c
--- src/libc/compat/stdlib/putenv.c	19 Jun 2001 19:51:38 -0000	1.4
+++ src/libc/compat/stdlib/putenv.c	10 Aug 2004 10:48:22 -0000
@@ -11,13 +11,13 @@

 /*

-   This routine assumes that the environ array and all strings it
+   This routine assumes that the _environ array and all strings it
    points to were malloc'd.  Nobody else should modify the environment
    except crt1.c

 */

-extern char **environ;
+extern char **_environ;
 static char **prev_environ = NULL; /* to know when it's safe to call `free' */
 static int ecount = -1;
 static int emax = -1;
@@ -49,14 +49,14 @@
   /* Force recomputation of the static counters.

      The second condition of the next if clause covers the case that
-     somebody pointed environ to another array, which invalidates
+     somebody pointed _environ to another array, which invalidates
      `ecount' and `emax'.  This can be used to change the environment
      to something entirely different, or to effectively discard it
      altogether.  GNU `env' from Sh-utils does just that.  */
   if (putenv_bss_count != __bss_count
-      || environ       != prev_environ)
+      || _environ      != prev_environ)
   {
-    for (ecount=0; environ[ecount]; ecount++);
+    for (ecount=0; _environ[ecount]; ecount++);
     emax = ecount;
     /* Bump the count to a value no function has yet seen,
        even if they were dumped with us.  */
@@ -64,29 +64,29 @@
     if (putenv_bss_count != __bss_count)
     {
       putenv_bss_count = __bss_count;
-      prev_environ = environ;	/* it's malloced by crt1.c */
+      prev_environ = _environ;	/* it's malloced by crt1.c */
     }
   }

-  for (eindex=0; environ[eindex]; eindex++)
-    if (strncmp(environ[eindex], val, nlen) == 0
-	&& (epos || environ[eindex][nlen] == '='))
+  for (eindex=0; _environ[eindex]; eindex++)
+    if (strncmp(_environ[eindex], val, nlen) == 0
+	&& (epos || _environ[eindex][nlen] == '='))
     {
-      char *oval = environ[eindex];
+      char *oval = _environ[eindex];
       int olen = strlen(oval);

       if (val[nlen] == 0 && !epos) /* delete the entry */
       {
 	free(oval);
-	environ[eindex] = environ[ecount-1];
-	environ[ecount-1] = 0;
+	_environ[eindex] = _environ[ecount-1];
+	_environ[ecount-1] = 0;
 	ecount--;
 	__environ_changed++;
 	return 0;
       }

       /* change existing entry */
-      if (strcmp(environ[eindex]+nlen, val+nlen) == 0)
+      if (strcmp(_environ[eindex]+nlen, val+nlen) == 0)
 	return 0; /* they're the same */

       /* If new is the same length as old, reuse the same
@@ -95,19 +95,19 @@
       if (vlen != olen)
       {
 	if (vlen > olen)
-	  environ[eindex] = (char *)malloc(vlen+1);
+	  _environ[eindex] = (char *)malloc(vlen+1);
 	else	/* vlen < olen */
-	  environ[eindex] = (char *)realloc(oval, vlen+1);
-	if (environ[eindex] == 0)
+	  _environ[eindex] = (char *)realloc(oval, vlen+1);
+	if (_environ[eindex] == 0)
 	{
-	  environ[eindex] = oval;
+	  _environ[eindex] = oval;
 	  errno = ENOMEM;
 	  return -1;
 	}
 	if (vlen > olen)
 	  free(oval);
       }
-      strcpy(environ[eindex], val);
+      strcpy(_environ[eindex], val);
       __environ_changed++;
       return 0;
     }
@@ -127,25 +127,25 @@
       errno = ENOMEM;
       return -1;
     }
-    memcpy(enew, environ, ecount * sizeof(char *));
-    /* If somebody set environ to another array, we can't
+    memcpy(enew, _environ, ecount * sizeof(char *));
+    /* If somebody set _environ to another array, we can't
        safely free it.  Better leak memory than crash.  */
-    if (environ == prev_environ)
-      free(environ);
-    environ = enew;
-    prev_environ = environ;
+    if (_environ == prev_environ)
+      free(_environ);
+    _environ = enew;
+    prev_environ = _environ;
   }

-  environ[ecount] = (char *)malloc(vlen+1);
-  if (environ[ecount] == 0)
+  _environ[ecount] = (char *)malloc(vlen+1);
+  if (_environ[ecount] == 0)
   {
     errno = ENOMEM;
     return -1;
   }
-  strcpy(environ[ecount], val);
+  strcpy(_environ[ecount], val);

   ecount++;
-  environ[ecount] = 0;
+  _environ[ecount] = 0;

   __environ_changed++;

Index: src/libc/crt0/crt1.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/crt0/crt1.c,v
retrieving revision 1.10
diff -u -r1.10 crt1.c
--- src/libc/crt0/crt1.c	10 May 2003 15:28:24 -0000	1.10
+++ src/libc/crt0/crt1.c	10 Aug 2004 10:48:22 -0000
@@ -35,7 +35,7 @@
    the static storage.  */
 int __bss_count = 1;

-char **environ;
+extern char **_environ;

 int __crt0_argc;
 char **__crt0_argv;
@@ -137,25 +137,25 @@
     while (*cp) cp++; /* skip to NUL */
     cp++; /* skip to next character */
   } while (*cp); /* repeat until two NULs */
-  environ = (char **)malloc((env_count+1) * sizeof(char *));
-  if (environ == 0)
+  _environ = (char **)malloc((env_count+1) * sizeof(char *));
+  if (_environ == 0)
     return;

   cp = dos_environ;
   env_count = 0;
   do {
     /* putenv assumes each string is malloc'd */
-    environ[env_count] = (char *)malloc(strlen(cp)+1);
-    strcpy(environ[env_count], cp);
+    _environ[env_count] = (char *)malloc(strlen(cp)+1);
+    strcpy(_environ[env_count], cp);
     env_count++;
     while (*cp) cp++; /* skip to NUL */
     cp++; /* skip to next character */
   } while (*cp); /* repeat until two NULs */
-  environ[env_count] = 0;
+  _environ[env_count] = 0;

   /*
    * Call putenv so that its static counters are computed. If this
-   * is not done, programs that manipulate `environ' directly will crash,
+   * is not done, programs that manipulate `_environ' directly will crash,
    * when `DJGPP' is not set in the environment.
    */
   putenv(unconst("", char *));
@@ -231,6 +231,6 @@
   _crt0_init_mcount();
   __main();
   errno = 0;	/* ANSI says errno should be zero at program startup */
-  exit(main(__crt0_argc, __crt0_argv, environ));
+  exit(main(__crt0_argc, __crt0_argv, _environ));
 }

Index: src/libc/dos/process/dosexec.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/process/dosexec.c,v
retrieving revision 1.21
diff -u -r1.21 dosexec.c
--- src/libc/dos/process/dosexec.c	10 May 2003 15:30:05 -0000	1.21
+++ src/libc/dos/process/dosexec.c	10 Aug 2004 10:48:22 -0000
@@ -34,7 +34,7 @@
 /* Maximum length of the command we can pass through CMDLINE=.  */
 #define CMDLINE_MAX  1023

-extern char **environ;
+extern char **_environ;

 int __dosexec_in_system = 0;

@@ -1167,9 +1167,9 @@
     if (strncmp(envp[i], "COMSPEC=", 8) == 0)
       comspec = envp[i]+8;
   if (!comspec)
-    for (i=0; environ[i]; i++)
-      if (strncmp(environ[i], "COMSPEC=", 8) == 0)
-        comspec = environ[i]+8;
+    for (i=0; _environ[i]; i++)
+      if (strncmp(_environ[i], "COMSPEC=", 8) == 0)
+        comspec = _environ[i]+8;
   if (!comspec)
     comspec = "c:\\command.com";

@@ -1535,7 +1535,7 @@

   /* Set defaults for the environment and search method.  */
   if (envpp == NULL)
-    envpp = environ;
+    envpp = _environ;

   if (flags == 0)
     flags |= SPAWN_EXTENSION_SRCH;
Index: src/libc/dos/process/spawnl.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/process/spawnl.c,v
retrieving revision 1.2
diff -u -r1.2 spawnl.c
--- src/libc/dos/process/spawnl.c	27 Sep 1998 14:52:50 -0000	1.2
+++ src/libc/dos/process/spawnl.c	10 Aug 2004 10:48:22 -0000
@@ -4,9 +4,9 @@
 #include <libc/unconst.h>
 #include <process.h>

-extern char **environ;
+extern char **_environ;

 int spawnl(int mode, const char *path, const char *argv0, ...)
 {
-  return spawnve(mode, path, unconst(&argv0,char * const *), environ);
+  return spawnve(mode, path, unconst(&argv0,char * const *), _environ);
 }
Index: src/libc/dos/process/spawnlp.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/process/spawnlp.c,v
retrieving revision 1.2
diff -u -r1.2 spawnlp.c
--- src/libc/dos/process/spawnlp.c	27 Sep 1998 14:52:50 -0000	1.2
+++ src/libc/dos/process/spawnlp.c	10 Aug 2004 10:48:22 -0000
@@ -4,10 +4,10 @@
 #include <libc/unconst.h>
 #include <process.h>

-extern char **environ;
+extern char **_environ;

 int spawnlp(int mode, const char *path, const char *argv0, ...)
 {
   return spawnvpe(mode, path, unconst(&argv0,char * const *),
-                              (char * const *)environ);
+                              (char * const *)_environ);
 }
Index: src/libc/dos/process/spawnv.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/process/spawnv.c,v
retrieving revision 1.1
diff -u -r1.1 spawnv.c
--- src/libc/dos/process/spawnv.c	11 Jan 1995 08:45:08 -0000	1.1
+++ src/libc/dos/process/spawnv.c	10 Aug 2004 10:48:22 -0000
@@ -2,9 +2,9 @@
 #include <libc/stubs.h>
 #include <process.h>

-extern char **environ;
+extern char **_environ;

 int spawnv(int mode, const char *path, char *const argv[])
 {
-  return spawnve(mode, path, (char * const *)argv, environ);
+  return spawnve(mode, path, (char * const *)argv, _environ);
 }
Index: src/libc/dos/process/spawnvp.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/process/spawnvp.c,v
retrieving revision 1.1
diff -u -r1.1 spawnvp.c
--- src/libc/dos/process/spawnvp.c	11 Jan 1995 08:45:08 -0000	1.1
+++ src/libc/dos/process/spawnvp.c	10 Aug 2004 10:48:22 -0000
@@ -2,9 +2,9 @@
 #include <libc/stubs.h>
 #include <process.h>

-extern char **environ;
+extern char **_environ;

 int spawnvp(int mode, const char *path, char *const argv[])
 {
-  return spawnvpe(mode, path, (char * const *)argv, environ);
+  return spawnvpe(mode, path, (char * const *)argv, _environ);
 }
Index: src/libc/posix/stdlib/unsetenv.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/stdlib/unsetenv.c,v
retrieving revision 1.3
diff -u -r1.3 unsetenv.c
--- src/libc/posix/stdlib/unsetenv.c	1 Dec 2001 20:06:01 -0000	1.3
+++ src/libc/posix/stdlib/unsetenv.c	10 Aug 2004 10:48:22 -0000
@@ -6,13 +6,13 @@
 #include <stdlib.h>
 #include <string.h>

-extern char **environ;
+extern char **_environ;

 int
 unsetenv(const char *name)
 {
   /* No environment == success */
-  if (environ == 0)
+  if (_environ == 0)
     return 0;

   /* Check for the failure conditions */
Index: src/libc/posix/unistd/execl.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/execl.c,v
retrieving revision 1.2
diff -u -r1.2 execl.c
--- src/libc/posix/unistd/execl.c	27 Sep 1998 14:52:52 -0000	1.2
+++ src/libc/posix/unistd/execl.c	10 Aug 2004 10:48:22 -0000
@@ -5,9 +5,9 @@
 #include <process.h>
 #include <libc/unconst.h>

-extern char *const *environ;
+extern char *const *_environ;

 int execl(const char *path, const char *argv0, ...)
 {
-  return spawnve(P_OVERLAY, path, unconst(&argv0,char *const*), environ);
+  return spawnve(P_OVERLAY, path, unconst(&argv0,char *const*), _environ);
 }
Index: src/libc/posix/unistd/execlp.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/execlp.c,v
retrieving revision 1.2
diff -u -r1.2 execlp.c
--- src/libc/posix/unistd/execlp.c	27 Sep 1998 14:52:52 -0000	1.2
+++ src/libc/posix/unistd/execlp.c	10 Aug 2004 10:48:22 -0000
@@ -6,9 +6,9 @@
 #include <libc/dosexec.h>
 #include <libc/unconst.h>

-extern char * const *environ;
+extern char * const *_environ;

 int execlp(const char *path, const char *argv0, ...)
 {
-  return spawnvpe(P_OVERLAY, path, unconst(&argv0,char * const *), environ);
+  return spawnvpe(P_OVERLAY, path, unconst(&argv0,char * const *), _environ);
 }
Index: src/libc/posix/unistd/execv.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/execv.c,v
retrieving revision 1.1
diff -u -r1.1 execv.c
--- src/libc/posix/unistd/execv.c	9 Oct 1995 00:21:18 -0000	1.1
+++ src/libc/posix/unistd/execv.c	10 Aug 2004 10:48:22 -0000
@@ -3,9 +3,9 @@
 #include <unistd.h>
 #include <process.h>

-extern char * const *environ;
+extern char * const *_environ;

 int execv(const char *path, char * const *argv)
 {
-  return spawnve(P_OVERLAY, path, argv, environ);
+  return spawnve(P_OVERLAY, path, argv, _environ);
 }
Index: src/libc/posix/unistd/execvp.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/execvp.c,v
retrieving revision 1.1
diff -u -r1.1 execvp.c
--- src/libc/posix/unistd/execvp.c	9 Oct 1995 00:21:08 -0000	1.1
+++ src/libc/posix/unistd/execvp.c	10 Aug 2004 10:48:22 -0000
@@ -3,9 +3,9 @@
 #include <unistd.h>
 #include <process.h>

-extern char *const *environ;
+extern char *const *_environ;

 int execvp(const char *path, char * const argv[])
 {
-  return spawnvpe(P_OVERLAY, path, argv, environ);
+  return spawnvpe(P_OVERLAY, path, argv, _environ);
 }


-- 
Esa Peuha
student of mathematics at the University of Helsinki
http://www.helsinki.fi/~peuha/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019