On Tue, Feb 19, 2013 at 10:37 PM, John W. Eaton <j...@octave.org> wrote:

> On 02/19/2013 05:46 PM, Paul Eggert wrote:
>
>> On 02/19/13 14:04, John W. Eaton wrote:
>>
>>> and also to use _putenv in the normal case when the argument string to
>>> putenv contains "VAR=VAL".
>>>
>>
>> Ouch, thanks for catching that; it suggests further
>> fixes.  Could you please try this patch to gnulib instead?
>>
>
> This version passes my tests and looks OK to me.
>

It doesn't for me, I've a bunch of new errors in the octave test suite.
This is due to the fact that putenv("VAR=") doesn't work as expected. As
far as I can see, the implementation assumes that _putenv will take
ownership of the string provided and copy the pointer into _environ. After
calling _putenv("VAR= ") (note the space in the value), it looks for the
string address in _environ and change the address found with the original
string "VAR=" (without the space).

However, _putenv will actually make a copy of the string provided and put
this new pointer into _environ. As the string search is based on the
address, it fails to find the string and to reset the value to the empty
string.

This can be demonstrated with the following code:

#include <stdlib.h>
#include <stdio.h>

int main (int argc, char **argv)
{
  const char * s = "MYVAR=MYVAL";
  char ** ep;

  _putenv (s);
  for (ep = _environ; *ep; ep++)
    if (strcmp (*ep, s) == 0)
      {
        printf ("*ep=%p, s=%p\n", *ep, s);
        printf ("*ep=%s, s=%s\n", *ep, s);
      }

  return 0;
}

When compiled with MSVC and run, it gives the following output:

*ep=00333230, s=00403000
*ep=MYVAR=MYVAL, s=MYVAR=MYVAL

Michael.

Reply via email to