/*** *stdenvp.c - standard _setenvp routine * * Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved. * *Purpose: * This module is called by the C start-up routine to set up "_environ". * Its sets up an array of pointers to strings in the environment. * The global symbol "_environ" is set to point to this array. * *******************************************************************************/ #include #include #include #include #include #include #include #include #ifndef CRTDLL #ifdef _MBCS /* * Flag to ensure multibyte ctype table is only initialized once */ extern int __mbctype_initialized; #endif /* _MBCS */ /* * Flag checked by getenv() and _putenv() to determine if the environment has * been initialized. */ extern int __env_initialized; #endif /* CRTDLL */ /*** *_setenvp - set up "envp" for C programs * *Purpose: * Reads the environment and build the envp array for C programs. * *Entry: * The environment strings occur at _aenvptr. * The list of environment strings is terminated by an extra null * byte. Thus two null bytes in a row indicate the end of the * last environment string and the end of the environment, resp. * *Exit: * "environ" points to a null-terminated list of pointers to ASCIZ * strings, each of which is of the form "VAR=VALUE". The strings * are copied from the environment area. This array of pointers will * be malloc'ed. The block pointed to by _aenvptr is deallocated. * *Uses: * Allocates space on the heap for the environment pointers. * *Exceptions: * If space cannot be allocated, program is terminated. * *******************************************************************************/ #ifdef WPRFLAG void __cdecl _wsetenvp ( #else /* WPRFLAG */ void __cdecl _setenvp ( #endif /* WPRFLAG */ void ) { _TSCHAR *p; _TSCHAR **env; /* _environ ptr traversal pointer */ int numstrings; /* number of environment strings */ int cchars; #if !defined (CRTDLL) && defined (_MBCS) /* If necessary, initialize the multibyte ctype table. */ if ( __mbctype_initialized == 0 ) __initmbctable(); #endif /* !defined (CRTDLL) && defined (_MBCS) */ numstrings = 0; #ifdef WPRFLAG p = _wenvptr; #else /* WPRFLAG */ p = _aenvptr; #endif /* WPRFLAG */ /* * NOTE: starting with single null indicates no environ. * Count the number of strings. Skip drive letter settings * ("=C:=C:\foo" type) by skipping all environment variables * that begin with '=' character. */ while (*p != _T('\0')) { /* don't count "=..." type */ if (*p != _T('=')) ++numstrings; p += _tcslen(p) + 1; } /* need pointer for each string, plus one null ptr at end */ if ( (_tenviron = env = (_TSCHAR **) _malloc_crt((numstrings+1) * sizeof(_TSCHAR *))) == NULL ) _amsg_exit(_RT_SPACEENV); /* copy strings to malloc'd memory and save pointers in _environ */ #ifdef WPRFLAG for ( p = _wenvptr ; *p != L'\0' ; p += cchars ) { #else /* WPRFLAG */ for ( p = _aenvptr ; *p != '\0' ; p += cchars ) { #endif /* WPRFLAG */ cchars = _tcslen(p) + 1; /* don't copy "=..." type */ if (*p != _T('=')) { if ( (*env = (_TSCHAR *)_malloc_crt(cchars * sizeof(_TSCHAR))) == NULL ) _amsg_exit(_RT_SPACEENV); _tcscpy(*env, p); env++; } } #ifdef WPRFLAG _free_crt(_wenvptr); _wenvptr = NULL; #else /* WPRFLAG */ _free_crt(_aenvptr); _aenvptr = NULL; #endif /* WPRFLAG */ /* and a final NULL pointer */ *env = NULL; #ifndef CRTDLL /* * Set flag for getenv() and _putenv() to know the environment * has been set up. */ __env_initialized = 1; #endif /* CRTDLL */ }