Mail Archives: djgpp-workers/2002/01/19/06:17:52
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 -