www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2002/01/19/06:17:52

X-Authentication-Warning: delorie.com: mailnull set sender to djgpp-workers-bounces using -f
Sender: rich AT phekda DOT freeserve DOT co DOT uk
Message-ID: <3C495559.C01A23AF@phekda.freeserve.co.uk>
Date: Sat, 19 Jan 2002 11:15:37 +0000
From: Richard Dawe <rich AT phekda DOT freeserve DOT co DOT uk>
X-Mailer: Mozilla 4.77 [en] (X11; U; Linux 2.2.19 i586)
X-Accept-Language: de,fr
MIME-Version: 1.0
To: djgpp-workers AT delorie DOT com
Subject: Re: env.exe crash - reproducible test program
References: <10201180538 DOT AA24590 AT clio DOT rice DOT edu>
Reply-To: djgpp-workers AT delorie DOT com

Hello.

Charles Sandmann wrote:
> The following program will crash when built with v2.04/cvs due to a free
> nonallocate block assert failure.  Fails on Win2K and Win95.
> 
> You must not have the DJGPP environment variable set to have it fail
> (if set, it runs).  Evil.

This use of putenv() seems to violate the requirements of the putenv code, viz
the comment at the top of src/libc/compat/stdlib/putenv.c:

/*

   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

*/

Furthermore, the draft D7 of the new POSIX standard has the following in the
page on getenv():

"Conforming applications are required not to modify environ directly, but to
use only the 
functions described here to manipulate the process environment as an abstract
object. Thus, the 
implementation of the environment access functions has complete control over
the data 
structure used to represent the environment (subject to the requirement that
environ be 
maintained as a list of strings with embedded equal signs for applications
that wish to scan the environment). This constraint allows the implementation
to properly manage the memory it 
allocates, either by using allocated storage for all variables (copying them
on the first invocation 
of setenv() or unsetenv( )), or keeping track of which strings are currently
in allocated space and 
which are not, via a separate table or some other means. This enables the
implementation to free any allocated space used by strings (and perhaps the
pointers to them) stored in environ when
unsetenv( ) is called."

So modifying 'environ' directly violates the new POSIX specification.
Fortunately it's pretty easy to work around the problem for DJGPP. Below a
modified version of your test program that works, because it uses malloc() to
allocate the dummy_environ. Looking at the env source code, I expect a similar
hack would do the trick.

Bye, Rich =]

---Start test program---
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

extern char **environ;

int main (int argc, char **argv, char **envp)
{
  /* We must malloc() environ, according to putenv() comments. */
  /*char *dummy_environ[1];*/
  char **dummy_environ;

  malloc_debug(3);

  dummy_environ = malloc(sizeof(char *) * 1);
  assert(dummy_environ);
  dummy_environ[0] = NULL;

  environ = dummy_environ;
  environ[0] = NULL;

  for (; *envp; envp++)
    putenv (*envp);

  while (*environ)
    puts (*environ++);

  return 0;
}
---End test program---

-- 
Richard Dawe [ http://www.phekda.freeserve.co.uk/richdawe/ ]

- Raw text -


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