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