Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
7.0 KiB

  1. /***
  2. *stdenvp.c - standard _setenvp routine
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * This module is called by the C start-up routine to set up "_environ".
  8. * Its sets up an array of pointers to strings in the environment.
  9. * The global symbol "_environ" is set to point to this array.
  10. *
  11. *Revision History:
  12. * 11-07-84 GFW initial version
  13. * 01-08-86 SKS Modified for OS/2
  14. * 05-21-86 SKS Call _stdalloc to get memory for strings
  15. * 09-04-86 SKS Added check to skip the "*C_FILE_INFO" string
  16. * 10-21-86 SKS Improved check for "*C_FILE_INFO"/"_C_FILE_INFO"
  17. * 02-19-88 SKS Handle case where environment starts with a single null
  18. * 05-10-88 JCR Modified code to accept far pointer from _stdalloc
  19. * 06-01-88 PHG Merged DLL and normal versions
  20. * 07-12-88 JCR Largely re-written: (1) split mem allocation into two
  21. * seperate malloc() calls to help simplify putenv(),
  22. * (2) stdalloc() no longer robs from stack, (3) cProc/cEnd
  23. * sequence, (4) misc cleanup
  24. * 09-20-88 WAJ Initial 386 version
  25. * 12-13-88 JCR Use rterr.inc parameters for runtime errors
  26. * 04-09-90 GJF Added #include <cruntime.h>. Made the calling type
  27. * _CALLTYPE1. Also, fixed the copyright and cleaned up
  28. * up the formatting a bit.
  29. * 06-05-90 GJF Changed error message interface.
  30. * 10-08-90 GJF New-style function declarator.
  31. * 10-31-90 GJF Fixed statement appending the final NULL (Stevewo
  32. * found the bug).
  33. * 12-11-90 SRW Changed to include <oscalls.h> and setup _environ
  34. * correctly for Win32
  35. * 01-21-91 GJF ANSI naming.
  36. * 02-07-91 SRW Change _WIN32_ specific code to allocate static copy
  37. * 02-18-91 SRW Change _WIN32_ specific code to allocate copy of
  38. * variable strings as well [_WIN32_]
  39. * 07-25-91 GJF Changed strupr to _strupr.
  40. * 03-31-92 DJM POSIX support.
  41. * 04-20-92 GJF Removed conversion to upper-case code for Win32.
  42. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  43. * 11-24-93 CFW Rip out Cruiser and filter out "=c:\foo" type.
  44. * 11-29-93 CFW Remove unused POSIX stuff, wide char enable.
  45. * 12-07-93 CFW Change _TCHAR to _TSCHAR.
  46. * 01-10-95 CFW Debug CRT allocs.
  47. * 04-07-95 CFW Free environment block on demand.
  48. * 07-03-95 GJF Always free environment block.
  49. * 02-20-96 SKS Set _aenvptr/_wenvptr to NULL after freeing what it
  50. * points to (a copy of environment strings).
  51. * 06-30-97 GJF Added explicit, conditional init. of the mbctype table.
  52. * Set __env_initialized flag. Also detab-ed.
  53. * 01-04-99 GJF Changes for 64-bit size_t.
  54. * 03-05-01 PML Don't AV if _aenvptr is NULL (vs7#174755).
  55. * 03-27-01 PML Return error instead of calling amsg_exit (vs7#231220)
  56. *
  57. *******************************************************************************/
  58. #include <cruntime.h>
  59. #include <string.h>
  60. #include <stdlib.h>
  61. #include <internal.h>
  62. #include <rterr.h>
  63. #include <oscalls.h>
  64. #include <tchar.h>
  65. #include <dbgint.h>
  66. #ifndef CRTDLL
  67. #ifdef _MBCS
  68. /*
  69. * Flag to ensure multibyte ctype table is only initialized once
  70. */
  71. extern int __mbctype_initialized;
  72. #endif
  73. /*
  74. * Flag checked by getenv() and _putenv() to determine if the environment has
  75. * been initialized.
  76. */
  77. extern int __env_initialized;
  78. #endif
  79. /***
  80. *_setenvp - set up "envp" for C programs
  81. *
  82. *Purpose:
  83. * Reads the environment and build the envp array for C programs.
  84. *
  85. *Entry:
  86. * The environment strings occur at _aenvptr.
  87. * The list of environment strings is terminated by an extra null
  88. * byte. Thus two null bytes in a row indicate the end of the
  89. * last environment string and the end of the environment, resp.
  90. *
  91. *Exit:
  92. * "environ" points to a null-terminated list of pointers to ASCIZ
  93. * strings, each of which is of the form "VAR=VALUE". The strings
  94. * are copied from the environment area. This array of pointers will
  95. * be malloc'ed. The block pointed to by _aenvptr is deallocated.
  96. *
  97. *Uses:
  98. * Allocates space on the heap for the environment pointers.
  99. *
  100. *Exceptions:
  101. * If space cannot be allocated, program is terminated.
  102. *
  103. *******************************************************************************/
  104. #ifdef WPRFLAG
  105. int __cdecl _wsetenvp (
  106. #else
  107. int __cdecl _setenvp (
  108. #endif
  109. void
  110. )
  111. {
  112. _TSCHAR *p;
  113. _TSCHAR **env; /* _environ ptr traversal pointer */
  114. int numstrings; /* number of environment strings */
  115. int cchars;
  116. #if !defined(CRTDLL) && defined(_MBCS)
  117. /* If necessary, initialize the multibyte ctype table. */
  118. if ( __mbctype_initialized == 0 )
  119. __initmbctable();
  120. #endif
  121. numstrings = 0;
  122. #ifdef WPRFLAG
  123. p = _wenvptr;
  124. #else
  125. p = _aenvptr;
  126. #endif
  127. /*
  128. * We called __crtGetEnvironmentStrings[AW] just before this,
  129. * so if _[aw]envptr is NULL, we failed to get the environment.
  130. * Return an error.
  131. */
  132. if (p == NULL)
  133. return -1;
  134. /*
  135. * NOTE: starting with single null indicates no environ.
  136. * Count the number of strings. Skip drive letter settings
  137. * ("=C:=C:\foo" type) by skipping all environment variables
  138. * that begin with '=' character.
  139. */
  140. while (*p != _T('\0')) {
  141. /* don't count "=..." type */
  142. if (*p != _T('='))
  143. ++numstrings;
  144. p += _tcslen(p) + 1;
  145. }
  146. /* need pointer for each string, plus one null ptr at end */
  147. if ( (_tenviron = env = (_TSCHAR **)
  148. _malloc_crt((numstrings+1) * sizeof(_TSCHAR *))) == NULL )
  149. return -1;
  150. /* copy strings to malloc'd memory and save pointers in _environ */
  151. #ifdef WPRFLAG
  152. for ( p = _wenvptr ; *p != L'\0' ; p += cchars )
  153. #else
  154. for ( p = _aenvptr ; *p != '\0' ; p += cchars )
  155. #endif
  156. {
  157. cchars = (int)_tcslen(p) + 1;
  158. /* don't copy "=..." type */
  159. if (*p != _T('=')) {
  160. if ( (*env = (_TSCHAR *)_malloc_crt(cchars * sizeof(_TSCHAR)))
  161. == NULL )
  162. {
  163. _free_crt(_tenviron);
  164. _tenviron = NULL;
  165. return -1;
  166. }
  167. _tcscpy(*env, p);
  168. env++;
  169. }
  170. }
  171. #ifdef WPRFLAG
  172. _free_crt(_wenvptr);
  173. _wenvptr = NULL;
  174. #else
  175. _free_crt(_aenvptr);
  176. _aenvptr = NULL;
  177. #endif
  178. /* and a final NULL pointer */
  179. *env = NULL;
  180. #ifndef CRTDLL
  181. /*
  182. * Set flag for getenv() and _putenv() to know the environment
  183. * has been set up.
  184. */
  185. __env_initialized = 1;
  186. #endif
  187. return 0;
  188. }