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 Sender: peuha AT sirppi DOT helsinki DOT fi To: djgpp-workers AT delorie DOT com Subject: Fix for environ pollution Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII 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 #include -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 #include /* 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 #include -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 #include -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 #include -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 #include -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 #include -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 #include -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 #include -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 #include -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 #include -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/