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 "wine/test.h" 22 #include <stdlib.h> 23 24 static const char *a_very_long_env_string = 25 "LIBRARY_PATH=" 26 "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/mingw32/3.4.2/;" 27 "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/;" 28 "/mingw/lib/gcc/mingw32/3.4.2/;" 29 "/usr/lib/gcc/mingw32/3.4.2/;" 30 "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/mingw32/3.4.2/../../../../mingw32/lib/mingw32/3.4.2/;" 31 "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/mingw32/3.4.2/../../../../mingw32/lib/;" 32 "/mingw/mingw32/lib/mingw32/3.4.2/;" 33 "/mingw/mingw32/lib/;" 34 "/mingw/lib/mingw32/3.4.2/;" 35 "/mingw/lib/;" 36 "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/mingw32/3.4.2/../../../mingw32/3.4.2/;" 37 "C:/Program Files/GLBasic/Compiler/platform/Win32/Bin/../lib/gcc/mingw32/3.4.2/../../../;" 38 "/mingw/lib/mingw32/3.4.2/;" 39 "/mingw/lib/;" 40 "/lib/mingw32/3.4.2/;" 41 "/lib/;" 42 "/usr/lib/mingw32/3.4.2/;" 43 "/usr/lib/"; 44 45 void __cdecl __getmainargs(int *, char ***, char ***, int, int *); 46 void __cdecl __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *); 47 48 static char ***(__cdecl *p__p__environ)(void); 49 static WCHAR ***(__cdecl *p__p__wenviron)(void); 50 static void (*p_get_environ)(char ***); 51 static void (*p_get_wenviron)(WCHAR ***); 52 53 static char ***p_environ; 54 static WCHAR ***p_wenviron; 55 56 static void init(void) 57 { 58 HMODULE hmod = GetModuleHandleA("msvcrt.dll"); 59 60 p__p__environ = (void *)GetProcAddress(hmod, "__p__environ"); 61 p__p__wenviron = (void *)GetProcAddress(hmod, "__p__wenviron"); 62 p_environ = (void *)GetProcAddress(hmod, "_environ"); 63 p_wenviron = (void *)GetProcAddress(hmod, "_wenviron"); 64 p_get_environ = (void *)GetProcAddress(hmod, "_get_environ"); 65 p_get_wenviron = (void *)GetProcAddress(hmod, "_get_wenviron"); 66 } 67 68 static void test_system(void) 69 { 70 int ret = system(NULL); 71 ok(ret == 1, "Expected system to return 1, got %d\n", ret); 72 73 ret = system("echo OK"); 74 ok(ret == 0, "Expected system to return 0, got %d\n", ret); 75 } 76 77 static void test__environ(void) 78 { 79 int argc; 80 char **argv, **envp = NULL; 81 int i, mode = 0; 82 83 ok( p_environ != NULL, "Expected the pointer to _environ to be non-NULL\n" ); 84 if (p_environ) 85 ok( *p_environ != NULL, "Expected _environ to be initialized on startup\n" ); 86 87 if (!p_environ || !*p_environ) 88 { 89 skip( "_environ pointers are not valid\n" ); 90 return; 91 } 92 93 /* Examine the returned pointer from __p__environ(), if available. */ 94 if (p__p__environ) 95 { 96 ok( *p__p__environ() == *p_environ, 97 "Expected _environ pointers to be identical\n" ); 98 } 99 else 100 skip( "__p__environ() is not available\n" ); 101 102 if (p_get_environ) 103 { 104 char **retptr; 105 p_get_environ(&retptr); 106 ok( retptr == *p_environ, 107 "Expected _environ pointers to be identical\n" ); 108 } 109 else 110 win_skip( "_get_environ() is not available\n" ); 111 112 /* Note that msvcrt from Windows versions older than Vista 113 * expects the mode pointer parameter to be valid.*/ 114 __getmainargs(&argc, &argv, &envp, 0, &mode); 115 116 ok( envp != NULL, "Expected initial environment block pointer to be non-NULL\n" ); 117 if (!envp) 118 { 119 skip( "Initial environment block pointer is not valid\n" ); 120 return; 121 } 122 123 for (i = 0; ; i++) 124 { 125 if ((*p_environ)[i]) 126 { 127 ok( envp[i] != NULL, "Expected environment block pointer element to be non-NULL\n" ); 128 ok( !strcmp((*p_environ)[i], envp[i]), 129 "Expected _environ and environment block pointer strings (%s vs. %s) to match\n", 130 (*p_environ)[i], envp[i] ); 131 } 132 else 133 { 134 ok( !envp[i], "Expected environment block pointer element to be NULL, got %p\n", envp[i] ); 135 break; 136 } 137 } 138 } 139 140 static void test__wenviron(void) 141 { 142 static const WCHAR cat_eq_dogW[] = {'c','a','t','=','d','o','g',0}; 143 static const WCHAR cat_eqW[] = {'c','a','t','=',0}; 144 145 int argc; 146 char **argv, **envp = NULL; 147 WCHAR **wargv, **wenvp = NULL; 148 int i, mode = 0; 149 150 ok( p_wenviron != NULL, "Expected the pointer to _wenviron to be non-NULL\n" ); 151 if (p_wenviron) 152 ok( *p_wenviron == NULL, "Expected _wenviron to be NULL, got %p\n", *p_wenviron ); 153 else 154 { 155 win_skip( "Pointer to _wenviron is not valid\n" ); 156 return; 157 } 158 159 /* Examine the returned pointer from __p__wenviron(), if available. */ 160 if (p__p__wenviron) 161 { 162 ok( *p__p__wenviron() == NULL, 163 "Expected _wenviron pointers to be NULL\n" ); 164 } 165 else 166 skip( "__p__wenviron() is not available\n" ); 167 168 if (p_get_wenviron) 169 { 170 WCHAR **retptr; 171 p_get_wenviron(&retptr); 172 ok( retptr == NULL, 173 "Expected _wenviron pointers to be NULL\n" ); 174 } 175 else 176 win_skip( "_get_wenviron() is not available\n" ); 177 178 /* __getmainargs doesn't initialize _wenviron. */ 179 __getmainargs(&argc, &argv, &envp, 0, &mode); 180 181 ok( *p_wenviron == NULL, "Expected _wenviron to be NULL, got %p\n", *p_wenviron); 182 ok( envp != NULL, "Expected initial environment block pointer to be non-NULL\n" ); 183 if (!envp) 184 { 185 skip( "Initial environment block pointer is not valid\n" ); 186 return; 187 } 188 189 /* Neither does calling the non-Unicode environment manipulation functions. */ 190 ok( _putenv("cat=dog") == 0, "failed setting cat=dog\n" ); 191 ok( *p_wenviron == NULL, "Expected _wenviron to be NULL, got %p\n", *p_wenviron); 192 ok( _putenv("cat=") == 0, "failed deleting cat\n" ); 193 194 /* _wenviron isn't initialized until __wgetmainargs is called or 195 * one of the Unicode environment manipulation functions is called. */ 196 ok( _wputenv(cat_eq_dogW) == 0, "failed setting cat=dog\n" ); 197 ok( *p_wenviron != NULL, "Expected _wenviron to be non-NULL\n" ); 198 ok( _wputenv(cat_eqW) == 0, "failed deleting cat\n" ); 199 200 __wgetmainargs(&argc, &wargv, &wenvp, 0, &mode); 201 202 ok( *p_wenviron != NULL, "Expected _wenviron to be non-NULL\n" ); 203 ok( wenvp != NULL, "Expected initial environment block pointer to be non-NULL\n" ); 204 if (!wenvp) 205 { 206 skip( "Initial environment block pointer is not valid\n" ); 207 return; 208 } 209 210 /* Examine the returned pointer from __p__wenviron(), 211 * if available, after _wenviron is initialized. */ 212 if (p__p__wenviron) 213 { 214 ok( *p__p__wenviron() == *p_wenviron, 215 "Expected _wenviron pointers to be identical\n" ); 216 } 217 218 if (p_get_wenviron) 219 { 220 WCHAR **retptr; 221 p_get_wenviron(&retptr); 222 ok( retptr == *p_wenviron, 223 "Expected _wenviron pointers to be identical\n" ); 224 } 225 226 for (i = 0; ; i++) 227 { 228 if ((*p_wenviron)[i]) 229 { 230 ok( wenvp[i] != NULL, "Expected environment block pointer element to be non-NULL\n" ); 231 ok( !winetest_strcmpW((*p_wenviron)[i], wenvp[i]), 232 "Expected _wenviron and environment block pointer strings (%s vs. %s) to match\n", 233 wine_dbgstr_w((*p_wenviron)[i]), wine_dbgstr_w(wenvp[i]) ); 234 } 235 else 236 { 237 ok( !wenvp[i], "Expected environment block pointer element to be NULL, got %p\n", wenvp[i] ); 238 break; 239 } 240 } 241 } 242 243 static void test_environment_manipulation(void) 244 { 245 ok( _putenv("cat=") == 0, "_putenv failed on deletion of nonexistent environment variable\n" ); 246 ok( _putenv("cat=dog") == 0, "failed setting cat=dog\n" ); 247 ok( strcmp(getenv("cat"), "dog") == 0, "getenv did not return 'dog'\n" ); 248 ok( _putenv("cat=") == 0, "failed deleting cat\n" ); 249 250 ok( _putenv("=") == -1, "should not accept '=' as input\n" ); 251 ok( _putenv("=dog") == -1, "should not accept '=dog' as input\n" ); 252 ok( _putenv(a_very_long_env_string) == 0, "_putenv failed for long environment string\n"); 253 254 ok( getenv("nonexistent") == NULL, "getenv should fail with nonexistent var name\n" ); 255 } 256 257 START_TEST(environ) 258 { 259 init(); 260 261 /* The environ tests should always be run first, as they assume 262 * that the process has not manipulated the environment. */ 263 test__environ(); 264 test__wenviron(); 265 test_environment_manipulation(); 266 test_system(); 267 } 268