Hello all. Attached is a patch that adds some test cases for msvcrt to test part of the behavior for _putenv() and changes _putenv() to conform to these tests. The test cases in this patch were verified against WinXP. This patch includes a new file (dlls/msvcrt/tests/environ.c). This patch should fix breakage with any program checking the return code from _putenv() when clearing an environment variable (midl.exe, for example). --Alastair Bridgewater
? tests/environ.c Index: environ.c =================================================================== RCS file: /home/wine/wine/dlls/msvcrt/environ.c,v retrieving revision 1.11 diff -u -r1.11 environ.c --- environ.c 24 Sep 2003 18:57:28 -0000 1.11 +++ environ.c 3 Jan 2004 00:21:35 -0000 @@ -80,6 +80,7 @@ char name[256], value[512]; char *dst = name; int ret; + DWORD lasterror; TRACE("%s\n", str); @@ -95,7 +96,11 @@ *dst++ = *str++; *dst = '\0'; - ret = !SetEnvironmentVariableA(name, value[0] ? value : NULL); + lasterror = GetLastError(); + ret = 0 - !SetEnvironmentVariableA(name, value[0] ? value : NULL); + if (ret && (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) ret = 0; + SetLastError(lasterror); + /* Update the __p__environ array only when already initialized */ if (MSVCRT__environ) MSVCRT__environ = msvcrt_SnapshotOfEnvironmentA(MSVCRT__environ); Index: tests/.cvsignore =================================================================== RCS file: /home/wine/wine/dlls/msvcrt/tests/.cvsignore,v retrieving revision 1.4 diff -u -r1.4 .cvsignore --- tests/.cvsignore 20 Nov 2003 23:41:13 -0000 1.4 +++ tests/.cvsignore 3 Jan 2004 00:21:35 -0000 @@ -1,5 +1,6 @@ Makefile cpp.ok +environ.ok file.ok heap.ok msvcrt_test.exe.spec.c Index: tests/Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/msvcrt/tests/Makefile.in,v retrieving revision 1.4 diff -u -r1.4 Makefile.in --- tests/Makefile.in 20 Nov 2003 23:41:13 -0000 1.4 +++ tests/Makefile.in 3 Jan 2004 00:21:35 -0000 @@ -8,6 +8,7 @@ CTESTS = \ cpp.c \ + environ.c \ file.c \ heap.c \ scanf.c --- /dev/null 1969-12-31 19:00:00.000000000 -0500 +++ tests/environ.c 2004-01-02 19:02:00.000000000 -0500 @@ -0,0 +1,56 @@ +/* + * Unit test suite for environment functions + * + * Copyright 2003 Alastair Bridgewater + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "wine/test.h" +#include <stdlib.h> +#include <windows.h> + +static void setenv_test_helper(char *teststring, int desired_result, + char *description) +{ + int result; + DWORD lasterror; + + SetLastError(0xdeadbeef); + result = _putenv(teststring); + lasterror = GetLastError(); + + ok(result == desired_result, "%s returned %d, should have returned %d.", + description, result, desired_result); + ok(lasterror == 0xdeadbeef, "%s changed GetLastError() result to %08lx.", + description, lasterror); +} + +static void test_setenv( void ) +{ + /* All cases tested on WinXP */ + + /* NOTE: unchecked case, _putenv(NULL), should throw an exception */ + setenv_test_helper("", -1, "_putenv with empty string"); + setenv_test_helper("=", -1, "_putenv of \"=\""); + setenv_test_helper("FNORD=42", 0, "_putenv of \"FNORD=42\""); + setenv_test_helper("FNORD=", 0, "_putenv of \"FNORD=\""); + setenv_test_helper("FNORD=", 0, "second _putenv of \"FNORD=\""); +} + +START_TEST(environ) +{ + test_setenv(); +}