delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1996/10/03/04:16:10

Date: Thu, 3 Oct 1996 10:11:54 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: djgpp-workers AT delorie DOT com
Subject: More defensive `putenv'
Message-Id: <Pine.SUN.3.91.961003100428.27330H-100000@is>
Mime-Version: 1.0

It seems that other implementations of `putenv' tolerate setting 
`environ' to something else, e.g. to start with a clean environment.  At 
least two programs in the GNU Sh-utils have something like this:

   char *dummy_environ[1];

   environ = dummy_environ;
   environ[0] = NULL;

Our `putenv' of course gets totally confused by this.  So here are some 
changes to make it more defensive, and also support ``putenv("foobar")'' 
(meaning delete "foobar") which some Sh-utils need.

*** src/libc/compat/stdlib/putenv.c~2	Sat Aug 10 16:08:36 1996
--- src/libc/compat/stdlib/putenv.c	Tue Oct  1 21:15:54 1996
***************
*** 15,20 ****
--- 15,21 ----
  */
  
  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;
  static int putenv_bss_count = -1;
***************
*** 37,60 ****
  {
    int vlen = strlen(val);
    char *epos = strchr(val, '=');
!   int nlen = epos - val + 1;
    int eindex;
  
!   if (putenv_bss_count != __bss_count)
    {
-     putenv_bss_count = __bss_count;
      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.  */
      __environ_changed++;
    }
  
-   if (epos == 0)
-     return -1;
- 
    for (eindex=0; environ[eindex]; eindex++)
!     if (strncmp(environ[eindex], val, nlen) == 0)
      {
        char *oval = environ[eindex];
  
--- 38,73 ----
  {
    int vlen = strlen(val);
    char *epos = strchr(val, '=');
!   /* Feature: VAL without a `=' means delete the entry.  GNU `putenv'
!      works that way, and `env' from GNU Sh-utils counts on this behavior.  */
!   int nlen = epos ? epos - val + 1 : vlen;
    int eindex;
  
!   /* 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
!      `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)
    {
      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.  */
      __environ_changed++;
+     if (putenv_bss_count != __bss_count)
+     {
+       putenv_bss_count = __bss_count;
+       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] == '='))
      {
        char *oval = environ[eindex];
  
***************
*** 92,103 ****
    {
      char **enew;
      emax += 10;
!     enew = (char **)malloc(emax * sizeof(char **));
      if (enew == 0)
        return -1;
      memcpy(enew, environ, ecount * sizeof(char *));
!     free(environ);
      environ = enew;
    }
  
    environ[ecount] = (char *)malloc(vlen+1);
--- 105,120 ----
    {
      char **enew;
      emax += 10;
!     enew = (char **)malloc(emax * sizeof(char *));
      if (enew == 0)
        return -1;
      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;
    }
  
    environ[ecount] = (char *)malloc(vlen+1);

- Raw text -


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