1c2c66affSColin Finck /* 2c2c66affSColin Finck * Unit tests for C library environment routines 3c2c66affSColin Finck * 4c2c66affSColin Finck * Copyright 2004 Mike Hearn <mh@codeweavers.com> 5c2c66affSColin Finck * 6c2c66affSColin Finck * This library is free software; you can redistribute it and/or 7c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public 8c2c66affSColin Finck * License as published by the Free Software Foundation; either 9c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version. 10c2c66affSColin Finck * 11c2c66affSColin Finck * This library is distributed in the hope that it will be useful, 12c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of 13c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14c2c66affSColin Finck * Lesser General Public License for more details. 15c2c66affSColin Finck * 16c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public 17c2c66affSColin Finck * License along with this library; if not, write to the Free Software 18c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19c2c66affSColin Finck */ 20c2c66affSColin Finck 21*1c9ac7a2SAmine Khaldi #include "wine/test.h" 22*1c9ac7a2SAmine Khaldi #include <stdlib.h> 23c2c66affSColin Finck 24c2c66affSColin Finck static const char *a_very_long_env_string = 25c2c66affSColin Finck "LIBRARY_PATH=" 26c2c66affSColin Finck "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/mingw32/3.4.2/;" 27c2c66affSColin Finck "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/;" 28c2c66affSColin Finck "/mingw/lib/gcc/mingw32/3.4.2/;" 29c2c66affSColin Finck "/usr/lib/gcc/mingw32/3.4.2/;" 30c2c66affSColin Finck "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/mingw32/3.4.2/../../../../mingw32/lib/mingw32/3.4.2/;" 31c2c66affSColin Finck "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/mingw32/3.4.2/../../../../mingw32/lib/;" 32c2c66affSColin Finck "/mingw/mingw32/lib/mingw32/3.4.2/;" 33c2c66affSColin Finck "/mingw/mingw32/lib/;" 34c2c66affSColin Finck "/mingw/lib/mingw32/3.4.2/;" 35c2c66affSColin Finck "/mingw/lib/;" 36c2c66affSColin Finck "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/mingw32/3.4.2/../../../mingw32/3.4.2/;" 37c2c66affSColin Finck "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/mingw32/3.4.2/../../../;" 38c2c66affSColin Finck "/mingw/lib/mingw32/3.4.2/;" 39c2c66affSColin Finck "/mingw/lib/;" 40c2c66affSColin Finck "/lib/mingw32/3.4.2/;" 41c2c66affSColin Finck "/lib/;" 42c2c66affSColin Finck "/usr/lib/mingw32/3.4.2/;" 43c2c66affSColin Finck "/usr/lib/"; 44c2c66affSColin Finck 45c2c66affSColin Finck void __cdecl __getmainargs(int *, char ***, char ***, int, int *); 46c2c66affSColin Finck void __cdecl __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *); 47c2c66affSColin Finck 48c2c66affSColin Finck static char ***(__cdecl *p__p__environ)(void); 49c2c66affSColin Finck static WCHAR ***(__cdecl *p__p__wenviron)(void); 50c2c66affSColin Finck 51c2c66affSColin Finck static char ***p_environ; 52c2c66affSColin Finck static WCHAR ***p_wenviron; 53c2c66affSColin Finck 54c2c66affSColin Finck static void init(void) 55c2c66affSColin Finck { 56c2c66affSColin Finck HMODULE hmod = GetModuleHandleA("msvcrt.dll"); 57c2c66affSColin Finck 58c2c66affSColin Finck p__p__environ = (void *)GetProcAddress(hmod, "__p__environ"); 59c2c66affSColin Finck p__p__wenviron = (void *)GetProcAddress(hmod, "__p__wenviron"); 60c2c66affSColin Finck p_environ = (void *)GetProcAddress(hmod, "_environ"); 61c2c66affSColin Finck p_wenviron = (void *)GetProcAddress(hmod, "_wenviron"); 62c2c66affSColin Finck } 63c2c66affSColin Finck 64c2c66affSColin Finck static void test_system(void) 65c2c66affSColin Finck { 66c2c66affSColin Finck int ret = system(NULL); 67c2c66affSColin Finck ok(ret == 1, "Expected system to return 1, got %d\n", ret); 68c2c66affSColin Finck 69c2c66affSColin Finck ret = system("echo OK"); 70c2c66affSColin Finck ok(ret == 0, "Expected system to return 0, got %d\n", ret); 71c2c66affSColin Finck } 72c2c66affSColin Finck 73c2c66affSColin Finck static void test__environ(void) 74c2c66affSColin Finck { 75c2c66affSColin Finck int argc; 76c2c66affSColin Finck char **argv, **envp = NULL; 77c2c66affSColin Finck int i, mode = 0; 78c2c66affSColin Finck 79c2c66affSColin Finck ok( p_environ != NULL, "Expected the pointer to _environ to be non-NULL\n" ); 80c2c66affSColin Finck if (p_environ) 81c2c66affSColin Finck ok( *p_environ != NULL, "Expected _environ to be initialized on startup\n" ); 82c2c66affSColin Finck 83c2c66affSColin Finck if (!p_environ || !*p_environ) 84c2c66affSColin Finck { 85c2c66affSColin Finck skip( "_environ pointers are not valid\n" ); 86c2c66affSColin Finck return; 87c2c66affSColin Finck } 88c2c66affSColin Finck 89c2c66affSColin Finck /* Examine the returned pointer from __p__environ(), if available. */ 90c2c66affSColin Finck if (p__p__environ) 91c2c66affSColin Finck { 92c2c66affSColin Finck ok( *p__p__environ() == *p_environ, 93c2c66affSColin Finck "Expected _environ pointers to be identical\n" ); 94c2c66affSColin Finck } 95c2c66affSColin Finck else 96c2c66affSColin Finck win_skip( "__p__environ() is not available\n" ); 97c2c66affSColin Finck 98c2c66affSColin Finck /* Note that msvcrt from Windows versions older than Vista 99c2c66affSColin Finck * expects the mode pointer parameter to be valid.*/ 100c2c66affSColin Finck __getmainargs(&argc, &argv, &envp, 0, &mode); 101c2c66affSColin Finck 102c2c66affSColin Finck ok( envp != NULL, "Expected initial environment block pointer to be non-NULL\n" ); 103c2c66affSColin Finck if (!envp) 104c2c66affSColin Finck { 105c2c66affSColin Finck skip( "Initial environment block pointer is not valid\n" ); 106c2c66affSColin Finck return; 107c2c66affSColin Finck } 108c2c66affSColin Finck 109c2c66affSColin Finck for (i = 0; ; i++) 110c2c66affSColin Finck { 111c2c66affSColin Finck if ((*p_environ)[i]) 112c2c66affSColin Finck { 113c2c66affSColin Finck ok( envp[i] != NULL, "Expected environment block pointer element to be non-NULL\n" ); 114c2c66affSColin Finck ok( !strcmp((*p_environ)[i], envp[i]), 115c2c66affSColin Finck "Expected _environ and environment block pointer strings (%s vs. %s) to match\n", 116c2c66affSColin Finck (*p_environ)[i], envp[i] ); 117c2c66affSColin Finck } 118c2c66affSColin Finck else 119c2c66affSColin Finck { 120c2c66affSColin Finck ok( !envp[i], "Expected environment block pointer element to be NULL, got %p\n", envp[i] ); 121c2c66affSColin Finck break; 122c2c66affSColin Finck } 123c2c66affSColin Finck } 124c2c66affSColin Finck } 125c2c66affSColin Finck 126c2c66affSColin Finck static void test__wenviron(void) 127c2c66affSColin Finck { 128c2c66affSColin Finck static const WCHAR cat_eq_dogW[] = {'c','a','t','=','d','o','g',0}; 129c2c66affSColin Finck static const WCHAR cat_eqW[] = {'c','a','t','=',0}; 130c2c66affSColin Finck 131c2c66affSColin Finck int argc; 132c2c66affSColin Finck char **argv, **envp = NULL; 133c2c66affSColin Finck WCHAR **wargv, **wenvp = NULL; 134c2c66affSColin Finck int i, mode = 0; 135c2c66affSColin Finck 136c2c66affSColin Finck ok( p_wenviron != NULL, "Expected the pointer to _wenviron to be non-NULL\n" ); 137c2c66affSColin Finck if (p_wenviron) 138c2c66affSColin Finck ok( *p_wenviron == NULL, "Expected _wenviron to be NULL, got %p\n", *p_wenviron ); 139c2c66affSColin Finck else 140c2c66affSColin Finck { 141c2c66affSColin Finck win_skip( "Pointer to _wenviron is not valid\n" ); 142c2c66affSColin Finck return; 143c2c66affSColin Finck } 144c2c66affSColin Finck 145c2c66affSColin Finck /* Examine the returned pointer from __p__wenviron(), if available. */ 146c2c66affSColin Finck if (p__p__wenviron) 147c2c66affSColin Finck { 148c2c66affSColin Finck ok( *p__p__wenviron() == NULL, 149c2c66affSColin Finck "Expected _wenviron pointers to be NULL\n" ); 150c2c66affSColin Finck } 151c2c66affSColin Finck else 152c2c66affSColin Finck win_skip( "__p__wenviron() is not available\n" ); 153c2c66affSColin Finck 154c2c66affSColin Finck /* __getmainargs doesn't initialize _wenviron. */ 155c2c66affSColin Finck __getmainargs(&argc, &argv, &envp, 0, &mode); 156c2c66affSColin Finck 157c2c66affSColin Finck ok( *p_wenviron == NULL, "Expected _wenviron to be NULL, got %p\n", *p_wenviron); 158c2c66affSColin Finck ok( envp != NULL, "Expected initial environment block pointer to be non-NULL\n" ); 159c2c66affSColin Finck if (!envp) 160c2c66affSColin Finck { 161c2c66affSColin Finck skip( "Initial environment block pointer is not valid\n" ); 162c2c66affSColin Finck return; 163c2c66affSColin Finck } 164c2c66affSColin Finck 165c2c66affSColin Finck /* Neither does calling the non-Unicode environment manipulation functions. */ 166c2c66affSColin Finck ok( _putenv("cat=dog") == 0, "failed setting cat=dog\n" ); 167c2c66affSColin Finck ok( *p_wenviron == NULL, "Expected _wenviron to be NULL, got %p\n", *p_wenviron); 168c2c66affSColin Finck ok( _putenv("cat=") == 0, "failed deleting cat\n" ); 169c2c66affSColin Finck 170c2c66affSColin Finck /* _wenviron isn't initialized until __wgetmainargs is called or 171c2c66affSColin Finck * one of the Unicode environment manipulation functions is called. */ 172c2c66affSColin Finck ok( _wputenv(cat_eq_dogW) == 0, "failed setting cat=dog\n" ); 173c2c66affSColin Finck ok( *p_wenviron != NULL, "Expected _wenviron to be non-NULL\n" ); 174c2c66affSColin Finck ok( _wputenv(cat_eqW) == 0, "failed deleting cat\n" ); 175c2c66affSColin Finck 176c2c66affSColin Finck __wgetmainargs(&argc, &wargv, &wenvp, 0, &mode); 177c2c66affSColin Finck 178c2c66affSColin Finck ok( *p_wenviron != NULL, "Expected _wenviron to be non-NULL\n" ); 179c2c66affSColin Finck ok( wenvp != NULL, "Expected initial environment block pointer to be non-NULL\n" ); 180c2c66affSColin Finck if (!wenvp) 181c2c66affSColin Finck { 182c2c66affSColin Finck skip( "Initial environment block pointer is not valid\n" ); 183c2c66affSColin Finck return; 184c2c66affSColin Finck } 185c2c66affSColin Finck 186c2c66affSColin Finck /* Examine the returned pointer from __p__wenviron(), 187c2c66affSColin Finck * if available, after _wenviron is initialized. */ 188c2c66affSColin Finck if (p__p__wenviron) 189c2c66affSColin Finck { 190c2c66affSColin Finck ok( *p__p__wenviron() == *p_wenviron, 191c2c66affSColin Finck "Expected _wenviron pointers to be identical\n" ); 192c2c66affSColin Finck } 193c2c66affSColin Finck 194c2c66affSColin Finck for (i = 0; ; i++) 195c2c66affSColin Finck { 196c2c66affSColin Finck if ((*p_wenviron)[i]) 197c2c66affSColin Finck { 198c2c66affSColin Finck ok( wenvp[i] != NULL, "Expected environment block pointer element to be non-NULL\n" ); 199c2c66affSColin Finck ok( !winetest_strcmpW((*p_wenviron)[i], wenvp[i]), 200c2c66affSColin Finck "Expected _wenviron and environment block pointer strings (%s vs. %s) to match\n", 201c2c66affSColin Finck wine_dbgstr_w((*p_wenviron)[i]), wine_dbgstr_w(wenvp[i]) ); 202c2c66affSColin Finck } 203c2c66affSColin Finck else 204c2c66affSColin Finck { 205c2c66affSColin Finck ok( !wenvp[i], "Expected environment block pointer element to be NULL, got %p\n", wenvp[i] ); 206c2c66affSColin Finck break; 207c2c66affSColin Finck } 208c2c66affSColin Finck } 209c2c66affSColin Finck } 210c2c66affSColin Finck 211c2c66affSColin Finck static void test_environment_manipulation(void) 212c2c66affSColin Finck { 213c2c66affSColin Finck ok( _putenv("cat=") == 0, "_putenv failed on deletion of nonexistent environment variable\n" ); 214c2c66affSColin Finck ok( _putenv("cat=dog") == 0, "failed setting cat=dog\n" ); 215c2c66affSColin Finck ok( strcmp(getenv("cat"), "dog") == 0, "getenv did not return 'dog'\n" ); 216c2c66affSColin Finck ok( _putenv("cat=") == 0, "failed deleting cat\n" ); 217c2c66affSColin Finck 218c2c66affSColin Finck ok( _putenv("=") == -1, "should not accept '=' as input\n" ); 219c2c66affSColin Finck ok( _putenv("=dog") == -1, "should not accept '=dog' as input\n" ); 220c2c66affSColin Finck ok( _putenv(a_very_long_env_string) == 0, "_putenv failed for long environment string\n"); 221c2c66affSColin Finck 222c2c66affSColin Finck ok( getenv("nonexistent") == NULL, "getenv should fail with nonexistent var name\n" ); 223c2c66affSColin Finck } 224c2c66affSColin Finck 225c2c66affSColin Finck START_TEST(environ) 226c2c66affSColin Finck { 227c2c66affSColin Finck init(); 228c2c66affSColin Finck 229c2c66affSColin Finck /* The environ tests should always be run first, as they assume 230c2c66affSColin Finck * that the process has not manipulated the environment. */ 231c2c66affSColin Finck test__environ(); 232c2c66affSColin Finck test__wenviron(); 233c2c66affSColin Finck test_environment_manipulation(); 234c2c66affSColin Finck test_system(); 235c2c66affSColin Finck } 236