home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / stdenvp.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  4KB  |  149 lines

  1. /***
  2. *stdenvp.c - standard _setenvp routine
  3. *
  4. *       Copyright (c) 1989-1997, 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. *******************************************************************************/
  12.  
  13. #include <cruntime.h>
  14. #include <string.h>
  15. #include <stdlib.h>
  16. #include <internal.h>
  17. #include <rterr.h>
  18. #include <oscalls.h>
  19. #include <tchar.h>
  20. #include <dbgint.h>
  21.  
  22. #ifndef CRTDLL
  23.  
  24. #ifdef _MBCS
  25. /*
  26.  * Flag to ensure multibyte ctype table is only initialized once
  27.  */
  28. extern int __mbctype_initialized;
  29.  
  30. #endif  /* _MBCS */
  31.  
  32. /*
  33.  * Flag checked by getenv() and _putenv() to determine if the environment has
  34.  * been initialized.
  35.  */
  36. extern int __env_initialized;
  37.  
  38. #endif  /* CRTDLL */
  39.  
  40. /***
  41. *_setenvp - set up "envp" for C programs
  42. *
  43. *Purpose:
  44. *       Reads the environment and build the envp array for C programs.
  45. *
  46. *Entry:
  47. *       The environment strings occur at _aenvptr.
  48. *       The list of environment strings is terminated by an extra null
  49. *       byte.  Thus two null bytes in a row indicate the end of the
  50. *       last environment string and the end of the environment, resp.
  51. *
  52. *Exit:
  53. *       "environ" points to a null-terminated list of pointers to ASCIZ
  54. *       strings, each of which is of the form "VAR=VALUE".  The strings
  55. *       are copied from the environment area. This array of pointers will
  56. *       be malloc'ed.  The block pointed to by _aenvptr is deallocated.
  57. *
  58. *Uses:
  59. *       Allocates space on the heap for the environment pointers.
  60. *
  61. *Exceptions:
  62. *       If space cannot be allocated, program is terminated.
  63. *
  64. *******************************************************************************/
  65.  
  66. #ifdef WPRFLAG
  67. void __cdecl _wsetenvp (
  68. #else  /* WPRFLAG */
  69. void __cdecl _setenvp (
  70. #endif  /* WPRFLAG */
  71.         void
  72.         )
  73. {
  74.         _TSCHAR *p;
  75.         _TSCHAR **env;              /* _environ ptr traversal pointer */
  76.         int numstrings;             /* number of environment strings */
  77.         int cchars;
  78.  
  79. #if !defined (CRTDLL) && defined (_MBCS)
  80.         /* If necessary, initialize the multibyte ctype table. */
  81.         if ( __mbctype_initialized == 0 )
  82.             __initmbctable();
  83. #endif  /* !defined (CRTDLL) && defined (_MBCS) */
  84.  
  85.         numstrings = 0;
  86.  
  87. #ifdef WPRFLAG
  88.         p = _wenvptr;
  89. #else  /* WPRFLAG */
  90.         p = _aenvptr;
  91. #endif  /* WPRFLAG */
  92.  
  93.         /*
  94.          * NOTE: starting with single null indicates no environ.
  95.          * Count the number of strings. Skip drive letter settings
  96.          * ("=C:=C:\foo" type) by skipping all environment variables
  97.          * that begin with '=' character.
  98.          */
  99.  
  100.         while (*p != _T('\0')) {
  101.             /* don't count "=..." type */
  102.             if (*p != _T('='))
  103.                 ++numstrings;
  104.             p += _tcslen(p) + 1;
  105.         }
  106.  
  107.         /* need pointer for each string, plus one null ptr at end */
  108.         if ( (_tenviron = env = (_TSCHAR **)
  109.             _malloc_crt((numstrings+1) * sizeof(_TSCHAR *))) == NULL )
  110.             _amsg_exit(_RT_SPACEENV);
  111.  
  112.         /* copy strings to malloc'd memory and save pointers in _environ */
  113. #ifdef WPRFLAG
  114.         for ( p = _wenvptr ; *p != L'\0' ; p += cchars ) {
  115. #else  /* WPRFLAG */
  116.         for ( p = _aenvptr ; *p != '\0' ; p += cchars ) {
  117. #endif  /* WPRFLAG */
  118.             cchars = _tcslen(p) + 1;
  119.             /* don't copy "=..." type */
  120.             if (*p != _T('=')) {
  121.                 if ( (*env = (_TSCHAR *)_malloc_crt(cchars * sizeof(_TSCHAR)))
  122.                      == NULL )
  123.                     _amsg_exit(_RT_SPACEENV);
  124.                 _tcscpy(*env, p);
  125.                 env++;
  126.             }
  127.         }
  128.  
  129. #ifdef WPRFLAG
  130.         _free_crt(_wenvptr);
  131.         _wenvptr = NULL;
  132. #else  /* WPRFLAG */
  133.         _free_crt(_aenvptr);
  134.         _aenvptr = NULL;
  135. #endif  /* WPRFLAG */
  136.  
  137.         /* and a final NULL pointer */
  138.         *env = NULL;
  139.  
  140. #ifndef CRTDLL
  141.         /*
  142.          * Set flag for getenv() and _putenv() to know the environment
  143.          * has been set up.
  144.          */
  145.         __env_initialized = 1;
  146. #endif  /* CRTDLL */
  147.  
  148. }
  149.