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