blob: 2cbd88b9a00ebe00c5fa4e814bf93b21db8912fc [file] [log] [blame]
Jim Cownie5e8470a2013-09-27 10:38:44 +00001/*
Jonathan Peytonde4749b2016-12-14 23:01:24 +00002 * kmp_environment.cpp -- Handle environment variables OS-independently.
Jim Cownie5e8470a2013-09-27 10:38:44 +00003 */
4
5
6//===----------------------------------------------------------------------===//
7//
8// The LLVM Compiler Infrastructure
9//
10// This file is dual licensed under the MIT and the University of Illinois Open
11// Source Licenses. See LICENSE.txt for details.
12//
13//===----------------------------------------------------------------------===//
14
15
Jonathan Peyton30419822017-05-12 18:01:32 +000016/* We use GetEnvironmentVariable for Windows* OS instead of getenv because the
17 act of loading a DLL on Windows* OS makes any user-set environment variables
18 (i.e. with putenv()) unavailable. getenv() apparently gets a clean copy of
19 the env variables as they existed at the start of the run. JH 12/23/2002
Jim Cownie5e8470a2013-09-27 10:38:44 +000020
Jonathan Peyton30419822017-05-12 18:01:32 +000021 On Windows* OS, there are two environments (at least, see below):
Jim Cownie5e8470a2013-09-27 10:38:44 +000022
Jonathan Peyton30419822017-05-12 18:01:32 +000023 1. Environment maintained by Windows* OS on IA-32 architecture. Accessible
24 through GetEnvironmentVariable(), SetEnvironmentVariable(), and
25 GetEnvironmentStrings().
Jim Cownie5e8470a2013-09-27 10:38:44 +000026
Jonathan Peyton30419822017-05-12 18:01:32 +000027 2. Environment maintained by C RTL. Accessible through getenv(), putenv().
Jim Cownie5e8470a2013-09-27 10:38:44 +000028
Jonathan Peyton30419822017-05-12 18:01:32 +000029 putenv() function updates both C and Windows* OS on IA-32 architecture.
30 getenv() function search for variables in C RTL environment only.
31 Windows* OS on IA-32 architecture functions work *only* with Windows* OS on
32 IA-32 architecture.
Jim Cownie5e8470a2013-09-27 10:38:44 +000033
Jonathan Peyton30419822017-05-12 18:01:32 +000034 Windows* OS on IA-32 architecture maintained by OS, so there is always only
35 one Windows* OS on IA-32 architecture per process. Changes in Windows* OS on
36 IA-32 architecture are process-visible.
Jim Cownie5e8470a2013-09-27 10:38:44 +000037
Jonathan Peyton30419822017-05-12 18:01:32 +000038 C environment maintained by C RTL. Multiple copies of C RTL may be present
39 in the process, and each C RTL maintains its own environment. :-(
Jim Cownie5e8470a2013-09-27 10:38:44 +000040
Jonathan Peyton30419822017-05-12 18:01:32 +000041 Thus, proper way to work with environment on Windows* OS is:
Jim Cownie5e8470a2013-09-27 10:38:44 +000042
Jonathan Peyton30419822017-05-12 18:01:32 +000043 1. Set variables with putenv() function -- both C and Windows* OS on IA-32
44 architecture are being updated. Windows* OS on IA-32 architecture may be
45 considered primary target, while updating C RTL environment is free bonus.
Jim Cownie5e8470a2013-09-27 10:38:44 +000046
Jonathan Peyton30419822017-05-12 18:01:32 +000047 2. Get variables with GetEnvironmentVariable() -- getenv() does not
48 search Windows* OS on IA-32 architecture, and can not see variables
49 set with SetEnvironmentVariable().
50
51 2007-04-05 -- lev
Jim Cownie5e8470a2013-09-27 10:38:44 +000052*/
53
54#include "kmp_environment.h"
55
Jonathan Peyton30419822017-05-12 18:01:32 +000056#include "kmp.h" //
Jim Cownie5e8470a2013-09-27 10:38:44 +000057#include "kmp_i18n.h"
Jonathan Peyton30419822017-05-12 18:01:32 +000058#include "kmp_os.h" // KMP_OS_*.
59#include "kmp_str.h" // __kmp_str_*().
Jim Cownie5e8470a2013-09-27 10:38:44 +000060
61#if KMP_OS_UNIX
Jonathan Peyton30419822017-05-12 18:01:32 +000062#include <stdlib.h> // getenv, setenv, unsetenv.
63#include <string.h> // strlen, strcpy.
64#if KMP_OS_DARWIN
65#include <crt_externs.h>
66#define environ (*_NSGetEnviron())
Jim Cownie5e8470a2013-09-27 10:38:44 +000067#else
Jonathan Peyton30419822017-05-12 18:01:32 +000068extern char **environ;
Jim Cownie5e8470a2013-09-27 10:38:44 +000069#endif
Jonathan Peyton30419822017-05-12 18:01:32 +000070#elif KMP_OS_WINDOWS
71#include <windows.h> // GetEnvironmentVariable, SetEnvironmentVariable,
72// GetLastError.
73#else
74#error Unknown or unsupported OS.
75#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +000076
77// TODO: Eliminate direct memory allocations, use string operations instead.
78
Jonathan Peyton30419822017-05-12 18:01:32 +000079static inline void *allocate(size_t size) {
80 void *ptr = KMP_INTERNAL_MALLOC(size);
81 if (ptr == NULL) {
82 KMP_FATAL(MemoryAllocFailed);
83 }; // if
84 return ptr;
Jim Cownie5e8470a2013-09-27 10:38:44 +000085} // allocate
86
Jonathan Peyton30419822017-05-12 18:01:32 +000087char *__kmp_env_get(char const *name) {
Jim Cownie5e8470a2013-09-27 10:38:44 +000088
Jonathan Peyton30419822017-05-12 18:01:32 +000089 char *result = NULL;
Jim Cownie5e8470a2013-09-27 10:38:44 +000090
Jonathan Peyton30419822017-05-12 18:01:32 +000091#if KMP_OS_UNIX
92 char const *value = getenv(name);
93 if (value != NULL) {
94 size_t len = KMP_STRLEN(value) + 1;
95 result = (char *)KMP_INTERNAL_MALLOC(len);
96 if (result == NULL) {
97 KMP_FATAL(MemoryAllocFailed);
98 }; // if
99 KMP_STRNCPY_S(result, len, value, len);
100 }; // if
101#elif KMP_OS_WINDOWS
102 /* We use GetEnvironmentVariable for Windows* OS instead of getenv because the
103 act of loading a DLL on Windows* OS makes any user-set environment
104 variables (i.e. with putenv()) unavailable. getenv() apparently gets a
105 clean copy of the env variables as they existed at the start of the run.
106 JH 12/23/2002 */
107 DWORD rc;
108 rc = GetEnvironmentVariable(name, NULL, 0);
109 if (!rc) {
110 DWORD error = GetLastError();
111 if (error != ERROR_ENVVAR_NOT_FOUND) {
112 __kmp_msg(kmp_ms_fatal, KMP_MSG(CantGetEnvVar, name), KMP_ERR(error),
113 __kmp_msg_null);
114 }; // if
115 // Variable is not found, it's ok, just continue.
116 } else {
117 DWORD len = rc;
118 result = (char *)KMP_INTERNAL_MALLOC(len);
119 if (result == NULL) {
120 KMP_FATAL(MemoryAllocFailed);
121 }; // if
122 rc = GetEnvironmentVariable(name, result, len);
123 if (!rc) {
124 // GetEnvironmentVariable() may return 0 if variable is empty.
125 // In such a case GetLastError() returns ERROR_SUCCESS.
126 DWORD error = GetLastError();
127 if (error != ERROR_SUCCESS) {
128 // Unexpected error. The variable should be in the environment,
129 // and buffer should be large enough.
130 __kmp_msg(kmp_ms_fatal, KMP_MSG(CantGetEnvVar, name), KMP_ERR(error),
131 __kmp_msg_null);
132 KMP_INTERNAL_FREE((void *)result);
133 result = NULL;
134 }; // if
135 }; // if
136 }; // if
137#else
138#error Unknown or unsupported OS.
139#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000140
Jonathan Peyton30419822017-05-12 18:01:32 +0000141 return result;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000142
143} // func __kmp_env_get
144
Jim Cownie5e8470a2013-09-27 10:38:44 +0000145// TODO: Find and replace all regular free() with __kmp_env_free().
146
Jonathan Peyton30419822017-05-12 18:01:32 +0000147void __kmp_env_free(char const **value) {
Jim Cownie5e8470a2013-09-27 10:38:44 +0000148
Jonathan Peyton30419822017-05-12 18:01:32 +0000149 KMP_DEBUG_ASSERT(value != NULL);
150 KMP_INTERNAL_FREE((void *)*value);
151 *value = NULL;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000152
153} // func __kmp_env_free
154
Jonathan Peyton30419822017-05-12 18:01:32 +0000155int __kmp_env_exists(char const *name) {
Jim Cownie5e8470a2013-09-27 10:38:44 +0000156
Jonathan Peyton30419822017-05-12 18:01:32 +0000157#if KMP_OS_UNIX
158 char const *value = getenv(name);
159 return ((value == NULL) ? (0) : (1));
160#elif KMP_OS_WINDOWS
161 DWORD rc;
162 rc = GetEnvironmentVariable(name, NULL, 0);
163 if (rc == 0) {
164 DWORD error = GetLastError();
165 if (error != ERROR_ENVVAR_NOT_FOUND) {
166 __kmp_msg(kmp_ms_fatal, KMP_MSG(CantGetEnvVar, name), KMP_ERR(error),
167 __kmp_msg_null);
168 }; // if
169 return 0;
170 }; // if
171 return 1;
172#else
173#error Unknown or unsupported OS.
174#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000175
176} // func __kmp_env_exists
177
Jonathan Peyton30419822017-05-12 18:01:32 +0000178void __kmp_env_set(char const *name, char const *value, int overwrite) {
Jim Cownie5e8470a2013-09-27 10:38:44 +0000179
Jonathan Peyton30419822017-05-12 18:01:32 +0000180#if KMP_OS_UNIX
181 int rc = setenv(name, value, overwrite);
182 if (rc != 0) {
183 // Dead code. I tried to put too many variables into Linux* OS
184 // environment on IA-32 architecture. When application consumes
185 // more than ~2.5 GB of memory, entire system feels bad. Sometimes
186 // application is killed (by OS?), sometimes system stops
187 // responding... But this error message never appears. --ln
188 __kmp_msg(kmp_ms_fatal, KMP_MSG(CantSetEnvVar, name),
189 KMP_HNT(NotEnoughMemory), __kmp_msg_null);
190 }; // if
191#elif KMP_OS_WINDOWS
192 BOOL rc;
193 if (!overwrite) {
194 rc = GetEnvironmentVariable(name, NULL, 0);
195 if (rc) {
196 // Variable exists, do not overwrite.
197 return;
198 }; // if
199 DWORD error = GetLastError();
200 if (error != ERROR_ENVVAR_NOT_FOUND) {
201 __kmp_msg(kmp_ms_fatal, KMP_MSG(CantGetEnvVar, name), KMP_ERR(error),
202 __kmp_msg_null);
203 }; // if
204 }; // if
205 rc = SetEnvironmentVariable(name, value);
206 if (!rc) {
207 DWORD error = GetLastError();
208 __kmp_msg(kmp_ms_fatal, KMP_MSG(CantSetEnvVar, name), KMP_ERR(error),
209 __kmp_msg_null);
210 }; // if
211#else
212#error Unknown or unsupported OS.
213#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000214
215} // func __kmp_env_set
216
Jonathan Peyton30419822017-05-12 18:01:32 +0000217void __kmp_env_unset(char const *name) {
Jim Cownie5e8470a2013-09-27 10:38:44 +0000218
Jonathan Peyton30419822017-05-12 18:01:32 +0000219#if KMP_OS_UNIX
220 unsetenv(name);
221#elif KMP_OS_WINDOWS
222 BOOL rc = SetEnvironmentVariable(name, NULL);
223 if (!rc) {
224 DWORD error = GetLastError();
225 __kmp_msg(kmp_ms_fatal, KMP_MSG(CantSetEnvVar, name), KMP_ERR(error),
226 __kmp_msg_null);
227 }; // if
228#else
229#error Unknown or unsupported OS.
230#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000231
232} // func __kmp_env_unset
233
Jonathan Peyton30419822017-05-12 18:01:32 +0000234/* Intel OpenMP RTL string representation of environment: just a string of
235 characters, variables are separated with vertical bars, e. g.:
Jim Cownie5e8470a2013-09-27 10:38:44 +0000236
237 "KMP_WARNINGS=0|KMP_AFFINITY=compact|"
238
239 Empty variables are allowed and ignored:
240
241 "||KMP_WARNINGS=1||"
Jim Cownie5e8470a2013-09-27 10:38:44 +0000242*/
243
Jonathan Peyton30419822017-05-12 18:01:32 +0000244static void
245___kmp_env_blk_parse_string(kmp_env_blk_t *block, // M: Env block to fill.
246 char const *env // I: String to parse.
247 ) {
Jim Cownie5e8470a2013-09-27 10:38:44 +0000248
Jonathan Peyton30419822017-05-12 18:01:32 +0000249 char const chr_delimiter = '|';
250 char const str_delimiter[] = {chr_delimiter, 0};
Jim Cownie5e8470a2013-09-27 10:38:44 +0000251
Jonathan Peyton30419822017-05-12 18:01:32 +0000252 char *bulk = NULL;
253 kmp_env_var_t *vars = NULL;
254 int count = 0; // Number of used elements in vars array.
255 int delimiters = 0; // Number of delimiters in input string.
Jim Cownie5e8470a2013-09-27 10:38:44 +0000256
Jonathan Peyton30419822017-05-12 18:01:32 +0000257 // Copy original string, we will modify the copy.
258 bulk = __kmp_str_format("%s", env);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000259
Jonathan Peyton30419822017-05-12 18:01:32 +0000260 // Loop thru all the vars in environment block. Count delimiters (maximum
261 // number of variables is number of delimiters plus one).
262 {
263 char const *ptr = bulk;
264 for (;;) {
265 ptr = strchr(ptr, chr_delimiter);
266 if (ptr == NULL) {
267 break;
268 }; // if
269 ++delimiters;
270 ptr += 1;
271 }; // forever
272 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000273
Jonathan Peyton30419822017-05-12 18:01:32 +0000274 // Allocate vars array.
275 vars = (kmp_env_var_t *)allocate((delimiters + 1) * sizeof(kmp_env_var_t));
Jim Cownie5e8470a2013-09-27 10:38:44 +0000276
Jonathan Peyton30419822017-05-12 18:01:32 +0000277 // Loop thru all the variables.
278 {
279 char *var; // Pointer to variable (both name and value).
280 char *name; // Pointer to name of variable.
281 char *value; // Pointer to value.
282 char *buf; // Buffer for __kmp_str_token() function.
283 var = __kmp_str_token(bulk, str_delimiter, &buf); // Get the first var.
284 while (var != NULL) {
285 // Save found variable in vars array.
286 __kmp_str_split(var, '=', &name, &value);
287 KMP_DEBUG_ASSERT(count < delimiters + 1);
288 vars[count].name = name;
289 vars[count].value = value;
290 ++count;
291 // Get the next var.
292 var = __kmp_str_token(NULL, str_delimiter, &buf);
293 }; // while
294 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000295
Jonathan Peyton30419822017-05-12 18:01:32 +0000296 // Fill out result.
297 block->bulk = bulk;
298 block->vars = vars;
299 block->count = count;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000300
301}; // ___kmp_env_blk_parse_string
302
Jonathan Peyton30419822017-05-12 18:01:32 +0000303/* Windows* OS (actually, DOS) environment block is a piece of memory with
304 environment variables. Each variable is terminated with zero byte, entire
305 block is terminated with one extra zero byte, so we have two zero bytes at
306 the end of environment block, e. g.:
Jim Cownie5e8470a2013-09-27 10:38:44 +0000307
308 "HOME=C:\\users\\lev\x00OS=Windows_NT\x00\x00"
309
310 It is not clear how empty environment is represented. "\x00\x00"?
311*/
312
Jonathan Peyton2321d572015-06-08 19:25:25 +0000313#if KMP_OS_WINDOWS
Jonathan Peyton30419822017-05-12 18:01:32 +0000314static void ___kmp_env_blk_parse_windows(
315 kmp_env_blk_t *block, // M: Env block to fill.
316 char const *env // I: Pointer to Windows* OS (DOS) environment block.
317 ) {
Jim Cownie5e8470a2013-09-27 10:38:44 +0000318
Jonathan Peyton30419822017-05-12 18:01:32 +0000319 char *bulk = NULL;
320 kmp_env_var_t *vars = NULL;
321 int count = 0; // Number of used elements in vars array.
322 int size = 0; // Size of bulk.
Jim Cownie5e8470a2013-09-27 10:38:44 +0000323
Jonathan Peyton30419822017-05-12 18:01:32 +0000324 char *name; // Pointer to name of variable.
325 char *value; // Pointer to value.
Jim Cownie5e8470a2013-09-27 10:38:44 +0000326
Jonathan Peyton30419822017-05-12 18:01:32 +0000327 if (env != NULL) {
Jim Cownie5e8470a2013-09-27 10:38:44 +0000328
Jonathan Peyton30419822017-05-12 18:01:32 +0000329 // Loop thru all the vars in environment block. Count variables, find size
330 // of block.
331 {
332 char const *var; // Pointer to beginning of var.
333 int len; // Length of variable.
334 count = 0;
335 var =
336 env; // The first variable starts and beginning of environment block.
337 len = KMP_STRLEN(var);
338 while (len != 0) {
339 ++count;
340 size = size + len + 1;
341 var = var + len +
342 1; // Move pointer to the beginning of the next variable.
343 len = KMP_STRLEN(var);
344 }; // while
345 size =
346 size + 1; // Total size of env block, including terminating zero byte.
347 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000348
Jonathan Peyton30419822017-05-12 18:01:32 +0000349 // Copy original block to bulk, we will modify bulk, not original block.
350 bulk = (char *)allocate(size);
351 KMP_MEMCPY_S(bulk, size, env, size);
352 // Allocate vars array.
353 vars = (kmp_env_var_t *)allocate(count * sizeof(kmp_env_var_t));
Jim Cownie5e8470a2013-09-27 10:38:44 +0000354
Jonathan Peyton30419822017-05-12 18:01:32 +0000355 // Loop thru all the vars, now in bulk.
356 {
357 char *var; // Pointer to beginning of var.
358 int len; // Length of variable.
359 count = 0;
360 var = bulk;
361 len = KMP_STRLEN(var);
362 while (len != 0) {
363 // Save variable in vars array.
364 __kmp_str_split(var, '=', &name, &value);
365 vars[count].name = name;
366 vars[count].value = value;
367 ++count;
368 // Get the next var.
369 var = var + len + 1;
370 len = KMP_STRLEN(var);
371 }; // while
372 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000373
Jonathan Peyton30419822017-05-12 18:01:32 +0000374 }; // if
Jim Cownie5e8470a2013-09-27 10:38:44 +0000375
Jonathan Peyton30419822017-05-12 18:01:32 +0000376 // Fill out result.
377 block->bulk = bulk;
378 block->vars = vars;
379 block->count = count;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000380
381}; // ___kmp_env_blk_parse_windows
Jonathan Peyton2321d572015-06-08 19:25:25 +0000382#endif
Jim Cownie5e8470a2013-09-27 10:38:44 +0000383
Jonathan Peyton30419822017-05-12 18:01:32 +0000384/* Unix environment block is a array of pointers to variables, last pointer in
385 array is NULL:
Jim Cownie5e8470a2013-09-27 10:38:44 +0000386
387 { "HOME=/home/lev", "TERM=xterm", NULL }
388*/
389
Jonathan Peyton30419822017-05-12 18:01:32 +0000390static void
391___kmp_env_blk_parse_unix(kmp_env_blk_t *block, // M: Env block to fill.
392 char **env // I: Unix environment to parse.
393 ) {
Jim Cownie5e8470a2013-09-27 10:38:44 +0000394
Jonathan Peyton30419822017-05-12 18:01:32 +0000395 char *bulk = NULL;
396 kmp_env_var_t *vars = NULL;
397 int count = 0;
398 int size = 0; // Size of bulk.
Jim Cownie5e8470a2013-09-27 10:38:44 +0000399
Jonathan Peyton30419822017-05-12 18:01:32 +0000400 // Count number of variables and length of required bulk.
401 {
402 count = 0;
403 size = 0;
404 while (env[count] != NULL) {
405 size += KMP_STRLEN(env[count]) + 1;
406 ++count;
407 }; // while
408 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000409
Jonathan Peyton30419822017-05-12 18:01:32 +0000410 // Allocate memory.
411 bulk = (char *)allocate(size);
412 vars = (kmp_env_var_t *)allocate(count * sizeof(kmp_env_var_t));
Jim Cownie5e8470a2013-09-27 10:38:44 +0000413
Jonathan Peyton30419822017-05-12 18:01:32 +0000414 // Loop thru all the vars.
415 {
416 char *var; // Pointer to beginning of var.
417 char *name; // Pointer to name of variable.
418 char *value; // Pointer to value.
419 int len; // Length of variable.
420 int i;
421 var = bulk;
422 for (i = 0; i < count; ++i) {
423 // Copy variable to bulk.
424 len = KMP_STRLEN(env[i]);
425 KMP_MEMCPY_S(var, size, env[i], len + 1);
426 // Save found variable in vars array.
427 __kmp_str_split(var, '=', &name, &value);
428 vars[i].name = name;
429 vars[i].value = value;
430 // Move pointer.
431 var += len + 1;
432 }; // for
433 }
Jim Cownie5e8470a2013-09-27 10:38:44 +0000434
Jonathan Peyton30419822017-05-12 18:01:32 +0000435 // Fill out result.
436 block->bulk = bulk;
437 block->vars = vars;
438 block->count = count;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000439
440}; // ___kmp_env_blk_parse_unix
441
Jonathan Peyton30419822017-05-12 18:01:32 +0000442void __kmp_env_blk_init(kmp_env_blk_t *block, // M: Block to initialize.
443 char const *bulk // I: Initialization string, or NULL.
444 ) {
Jim Cownie5e8470a2013-09-27 10:38:44 +0000445
Jonathan Peyton30419822017-05-12 18:01:32 +0000446 if (bulk != NULL) {
447 ___kmp_env_blk_parse_string(block, bulk);
448 } else {
449#if KMP_OS_UNIX
450 ___kmp_env_blk_parse_unix(block, environ);
451#elif KMP_OS_WINDOWS
452 {
453 char *mem = GetEnvironmentStrings();
454 if (mem == NULL) {
455 DWORD error = GetLastError();
456 __kmp_msg(kmp_ms_fatal, KMP_MSG(CantGetEnvironment), KMP_ERR(error),
457 __kmp_msg_null);
458 }; // if
459 ___kmp_env_blk_parse_windows(block, mem);
460 FreeEnvironmentStrings(mem);
461 }
462#else
463#error Unknown or unsupported OS.
464#endif
465 }; // if
Jim Cownie5e8470a2013-09-27 10:38:44 +0000466
467} // __kmp_env_blk_init
468
Jonathan Peyton30419822017-05-12 18:01:32 +0000469static int ___kmp_env_var_cmp( // Comparison function for qsort().
470 kmp_env_var_t const *lhs, kmp_env_var_t const *rhs) {
471 return strcmp(lhs->name, rhs->name);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000472}
473
Jonathan Peyton30419822017-05-12 18:01:32 +0000474void __kmp_env_blk_sort(
475 kmp_env_blk_t *block // M: Block of environment variables to sort.
476 ) {
Jim Cownie5e8470a2013-09-27 10:38:44 +0000477
Jonathan Peyton30419822017-05-12 18:01:32 +0000478 qsort((void *)block->vars, block->count, sizeof(kmp_env_var_t),
479 (int (*)(void const *, void const *)) & ___kmp_env_var_cmp);
Jim Cownie5e8470a2013-09-27 10:38:44 +0000480
481} // __kmp_env_block_sort
482
Jonathan Peyton30419822017-05-12 18:01:32 +0000483void __kmp_env_blk_free(
484 kmp_env_blk_t *block // M: Block of environment variables to free.
485 ) {
Jim Cownie5e8470a2013-09-27 10:38:44 +0000486
Jonathan Peyton30419822017-05-12 18:01:32 +0000487 KMP_INTERNAL_FREE((void *)block->vars);
488 __kmp_str_free(&(block->bulk));
Jim Cownie5e8470a2013-09-27 10:38:44 +0000489
Jonathan Peyton30419822017-05-12 18:01:32 +0000490 block->count = 0;
491 block->vars = NULL;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000492
493} // __kmp_env_blk_free
494
Jonathan Peyton30419822017-05-12 18:01:32 +0000495char const * // R: Value of variable or NULL if variable does not exist.
496 __kmp_env_blk_var(
497 kmp_env_blk_t *block, // I: Block of environment variables.
498 char const *name // I: Name of variable to find.
499 ) {
Jim Cownie5e8470a2013-09-27 10:38:44 +0000500
Jonathan Peyton30419822017-05-12 18:01:32 +0000501 int i;
502 for (i = 0; i < block->count; ++i) {
503 if (strcmp(block->vars[i].name, name) == 0) {
504 return block->vars[i].value;
505 }; // if
506 }; // for
507 return NULL;
Jim Cownie5e8470a2013-09-27 10:38:44 +0000508
509} // __kmp_env_block_var
510
Jim Cownie5e8470a2013-09-27 10:38:44 +0000511// end of file //