00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 #include "kmp_environment.h"
00089
00090 #include "kmp_os.h"
00091 #include "kmp.h"
00092 #include "kmp_str.h"
00093 #include "kmp_i18n.h"
00094
00095 #if KMP_OS_UNIX
00096 #include <stdlib.h>
00097 #include <string.h>
00098 #if KMP_OS_LINUX
00099 extern char * * environ;
00100 #elif KMP_OS_DARWIN
00101 #include <crt_externs.h>
00102 #define environ (*_NSGetEnviron())
00103 #else
00104 #error Unknown or unsupported OS.
00105 #endif
00106 #elif KMP_OS_WINDOWS
00107 #include <windows.h>
00108 #else
00109 #error Unknown or unsupported OS.
00110 #endif
00111
00112
00113
00114
00115 static inline
00116 void *
00117 allocate(
00118 size_t size
00119 ) {
00120 void * ptr = KMP_INTERNAL_MALLOC( size );
00121 if ( ptr == NULL ) {
00122 KMP_FATAL( MemoryAllocFailed );
00123 };
00124 return ptr;
00125 }
00126
00127
00128 char *
00129 __kmp_env_get( char const * name ) {
00130
00131 char * result = NULL;
00132
00133 #if KMP_OS_UNIX
00134 char const * value = getenv( name );
00135 if ( value != NULL ) {
00136 size_t len = strlen( value ) + 1;
00137 result = (char *) KMP_INTERNAL_MALLOC( len );
00138 if ( result == NULL ) {
00139 KMP_FATAL( MemoryAllocFailed );
00140 };
00141 strncpy( result, value, len );
00142 };
00143 #elif KMP_OS_WINDOWS
00144
00145
00146
00147
00148
00149
00150
00151 DWORD rc;
00152 rc = GetEnvironmentVariable( name, NULL, 0 );
00153 if ( ! rc ) {
00154 DWORD error = GetLastError();
00155 if ( error != ERROR_ENVVAR_NOT_FOUND ) {
00156 __kmp_msg(
00157 kmp_ms_fatal,
00158 KMP_MSG( CantGetEnvVar, name ),
00159 KMP_ERR( error ),
00160 __kmp_msg_null
00161 );
00162 };
00163
00164 } else {
00165 DWORD len = rc;
00166 result = (char *) KMP_INTERNAL_MALLOC( len );
00167 if ( result == NULL ) {
00168 KMP_FATAL( MemoryAllocFailed );
00169 };
00170 rc = GetEnvironmentVariable( name, result, len );
00171 if ( ! rc ) {
00172
00173
00174 DWORD error = GetLastError();
00175 if ( error != ERROR_SUCCESS ) {
00176
00177
00178 __kmp_msg(
00179 kmp_ms_fatal,
00180 KMP_MSG( CantGetEnvVar, name ),
00181 KMP_ERR( error ),
00182 __kmp_msg_null
00183 );
00184 KMP_INTERNAL_FREE( (void *) result );
00185 result = NULL;
00186 };
00187 };
00188 };
00189 #else
00190 #error Unknown or unsupported OS.
00191 #endif
00192
00193 return result;
00194
00195 }
00196
00197
00198
00199
00200 void
00201 __kmp_env_free( char const * * value ) {
00202
00203 KMP_DEBUG_ASSERT( value != NULL );
00204 KMP_INTERNAL_FREE( (void *) * value );
00205 * value = NULL;
00206
00207 }
00208
00209
00210
00211 int
00212 __kmp_env_exists( char const * name ) {
00213
00214 #if KMP_OS_UNIX
00215 char const * value = getenv( name );
00216 return ( ( value == NULL ) ? ( 0 ) : ( 1 ) );
00217 #elif KMP_OS_WINDOWS
00218 DWORD rc;
00219 rc = GetEnvironmentVariable( name, NULL, 0 );
00220 if ( rc == 0 ) {
00221 DWORD error = GetLastError();
00222 if ( error != ERROR_ENVVAR_NOT_FOUND ) {
00223 __kmp_msg(
00224 kmp_ms_fatal,
00225 KMP_MSG( CantGetEnvVar, name ),
00226 KMP_ERR( error ),
00227 __kmp_msg_null
00228 );
00229 };
00230 return 0;
00231 };
00232 return 1;
00233 #else
00234 #error Unknown or unsupported OS.
00235 #endif
00236
00237 }
00238
00239
00240
00241 void
00242 __kmp_env_set( char const * name, char const * value, int overwrite ) {
00243
00244 #if KMP_OS_UNIX
00245 int rc = setenv( name, value, overwrite );
00246 if ( rc != 0 ) {
00247
00248
00249
00250
00251
00252 __kmp_msg(
00253 kmp_ms_fatal,
00254 KMP_MSG( CantSetEnvVar, name ),
00255 KMP_HNT( NotEnoughMemory ),
00256 __kmp_msg_null
00257 );
00258 };
00259 #elif KMP_OS_WINDOWS
00260 BOOL rc;
00261 if ( ! overwrite ) {
00262 rc = GetEnvironmentVariable( name, NULL, 0 );
00263 if ( rc ) {
00264
00265 return;
00266 };
00267 DWORD error = GetLastError();
00268 if ( error != ERROR_ENVVAR_NOT_FOUND ) {
00269 __kmp_msg(
00270 kmp_ms_fatal,
00271 KMP_MSG( CantGetEnvVar, name ),
00272 KMP_ERR( error ),
00273 __kmp_msg_null
00274 );
00275 };
00276 };
00277 rc = SetEnvironmentVariable( name, value );
00278 if ( ! rc ) {
00279 DWORD error = GetLastError();
00280 __kmp_msg(
00281 kmp_ms_fatal,
00282 KMP_MSG( CantSetEnvVar, name ),
00283 KMP_ERR( error ),
00284 __kmp_msg_null
00285 );
00286 };
00287 #else
00288 #error Unknown or unsupported OS.
00289 #endif
00290
00291 }
00292
00293
00294
00295 void
00296 __kmp_env_unset( char const * name ) {
00297
00298 #if KMP_OS_UNIX
00299 unsetenv( name );
00300 #elif KMP_OS_WINDOWS
00301 BOOL rc = SetEnvironmentVariable( name, NULL );
00302 if ( ! rc ) {
00303 DWORD error = GetLastError();
00304 __kmp_msg(
00305 kmp_ms_fatal,
00306 KMP_MSG( CantSetEnvVar, name ),
00307 KMP_ERR( error ),
00308 __kmp_msg_null
00309 );
00310 };
00311 #else
00312 #error Unknown or unsupported OS.
00313 #endif
00314
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 static
00332 void
00333 ___kmp_env_blk_parse_string(
00334 kmp_env_blk_t * block,
00335 char const * env
00336 ) {
00337
00338 char const chr_delimiter = '|';
00339 char const str_delimiter[] = { chr_delimiter, 0 };
00340
00341 char * bulk = NULL;
00342 kmp_env_var_t * vars = NULL;
00343 int count = 0;
00344 int delimiters = 0;
00345
00346
00347 bulk = __kmp_str_format( "%s", env );
00348
00349
00350
00351 {
00352 char const * ptr = bulk;
00353 for ( ; ; ) {
00354 ptr = strchr( ptr, chr_delimiter );
00355 if ( ptr == NULL ) {
00356 break;
00357 };
00358 ++ delimiters;
00359 ptr += 1;
00360 };
00361 }
00362
00363
00364 vars = (kmp_env_var_t *) allocate( ( delimiters + 1 ) * sizeof( kmp_env_var_t ) );
00365
00366
00367 {
00368 char * var;
00369 char * name;
00370 char * value;
00371 char * buf;
00372 var = __kmp_str_token( bulk, str_delimiter, & buf );
00373 while ( var != NULL ) {
00374
00375 __kmp_str_split( var, '=', & name, & value );
00376 KMP_DEBUG_ASSERT( count < delimiters + 1 );
00377 vars[ count ].name = name;
00378 vars[ count ].value = value;
00379 ++ count;
00380
00381 var = __kmp_str_token( NULL, str_delimiter, & buf );
00382 };
00383 }
00384
00385
00386 block->bulk = bulk;
00387 block->vars = vars;
00388 block->count = count;
00389
00390 };
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 static
00405 void
00406 ___kmp_env_blk_parse_windows(
00407 kmp_env_blk_t * block,
00408 char const * env
00409 ) {
00410
00411 char * bulk = NULL;
00412 kmp_env_var_t * vars = NULL;
00413 int count = 0;
00414 int size = 0;
00415
00416 char * name;
00417 char * value;
00418
00419 if ( env != NULL ) {
00420
00421
00422 {
00423 char const * var;
00424 int len;
00425 count = 0;
00426 var = env;
00427 len = strlen( var );
00428 while ( len != 0 ) {
00429 ++ count;
00430 size = size + len + 1;
00431 var = var + len + 1;
00432 len = strlen( var );
00433 };
00434 size = size + 1;
00435 }
00436
00437
00438 bulk = (char *) allocate( size );
00439 memcpy( bulk, env, size );
00440
00441 vars = (kmp_env_var_t *) allocate( count * sizeof( kmp_env_var_t ) );
00442
00443
00444 {
00445 char * var;
00446 int len;
00447 count = 0;
00448 var = bulk;
00449 len = strlen( var );
00450 while ( len != 0 ) {
00451
00452 __kmp_str_split( var, '=', & name, & value );
00453 vars[ count ].name = name;
00454 vars[ count ].value = value;
00455 ++ count;
00456
00457 var = var + len + 1;
00458 len = strlen( var );
00459 };
00460 }
00461
00462 };
00463
00464
00465 block->bulk = bulk;
00466 block->vars = vars;
00467 block->count = count;
00468
00469 };
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 static
00480 void
00481 ___kmp_env_blk_parse_unix(
00482 kmp_env_blk_t * block,
00483 char * * env
00484 ) {
00485
00486 char * bulk = NULL;
00487 kmp_env_var_t * vars = NULL;
00488 int count = 0;
00489 int size = 0;
00490
00491
00492 {
00493 count = 0;
00494 size = 0;
00495 while ( env[ count ] != NULL ) {
00496 size += strlen( env[ count ] ) + 1;
00497 ++ count;
00498 };
00499 }
00500
00501
00502 bulk = (char *) allocate( size );
00503 vars = (kmp_env_var_t *) allocate( count * sizeof( kmp_env_var_t ) );
00504
00505
00506 {
00507 char * var;
00508 char * name;
00509 char * value;
00510 int len;
00511 int i;
00512 var = bulk;
00513 for ( i = 0; i < count; ++ i ) {
00514
00515 len = strlen( env[ i ] );
00516 memcpy( var, env[ i ], len + 1 );
00517
00518 __kmp_str_split( var, '=', & name, & value );
00519 vars[ i ].name = name;
00520 vars[ i ].value = value;
00521
00522 var += len + 1;
00523 };
00524 }
00525
00526
00527 block->bulk = bulk;
00528 block->vars = vars;
00529 block->count = count;
00530
00531 };
00532
00533
00534
00535 void
00536 __kmp_env_blk_init(
00537 kmp_env_blk_t * block,
00538 char const * bulk
00539 ) {
00540
00541 if ( bulk != NULL ) {
00542 ___kmp_env_blk_parse_string( block, bulk );
00543 } else {
00544 #if KMP_OS_UNIX
00545 ___kmp_env_blk_parse_unix( block, environ );
00546 #elif KMP_OS_WINDOWS
00547 {
00548 char * mem = GetEnvironmentStrings();
00549 if ( mem == NULL ) {
00550 DWORD error = GetLastError();
00551 __kmp_msg(
00552 kmp_ms_fatal,
00553 KMP_MSG( CantGetEnvironment ),
00554 KMP_ERR( error ),
00555 __kmp_msg_null
00556 );
00557 };
00558 ___kmp_env_blk_parse_windows( block, mem );
00559 FreeEnvironmentStrings( mem );
00560 }
00561 #else
00562 #error Unknown or unsupported OS.
00563 #endif
00564 };
00565
00566 }
00567
00568
00569
00570 static
00571 int
00572 ___kmp_env_var_cmp(
00573 kmp_env_var_t const * lhs,
00574 kmp_env_var_t const * rhs
00575 ) {
00576 return strcmp( lhs->name, rhs->name );
00577 }
00578
00579 void
00580 __kmp_env_blk_sort(
00581 kmp_env_blk_t * block
00582 ) {
00583
00584 qsort(
00585 (void *) block->vars,
00586 block->count,
00587 sizeof( kmp_env_var_t ),
00588 ( int ( * )( void const *, void const * ) ) & ___kmp_env_var_cmp
00589 );
00590
00591 }
00592
00593
00594
00595 void
00596 __kmp_env_blk_free(
00597 kmp_env_blk_t * block
00598 ) {
00599
00600 KMP_INTERNAL_FREE( (void *) block->vars );
00601 KMP_INTERNAL_FREE( (void *) block->bulk );
00602
00603 block->count = 0;
00604 block->vars = NULL;
00605 block->bulk = NULL;
00606
00607 }
00608
00609
00610
00611 char const *
00612 __kmp_env_blk_var(
00613 kmp_env_blk_t * block,
00614 char const * name
00615 ) {
00616
00617 int i;
00618 for ( i = 0; i < block->count; ++ i ) {
00619 if ( strcmp( block->vars[ i ].name, name ) == 0 ) {
00620 return block->vars[ i ].value;
00621 };
00622 };
00623 return NULL;
00624
00625 }
00626
00627
00628