home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c065 / 2.ddi / CLIB2.ZIP / PUTENV.CAS < prev    next >
Encoding:
Text File  |  1990-06-07  |  6.6 KB  |  215 lines

  1. /*-----------------------------------------------------------------------*
  2.  * filename - putenv.cas
  3.  *
  4.  * function(s)
  5.  *        putenv - adds string to current environment
  6.  *-----------------------------------------------------------------------*/
  7.  
  8. /*[]------------------------------------------------------------[]*/
  9. /*|                                                              |*/
  10. /*|     Turbo C Run Time Library - Version 3.0                   |*/
  11. /*|                                                              |*/
  12. /*|                                                              |*/
  13. /*|     Copyright (c) 1987,1988,1990 by Borland International    |*/
  14. /*|     All Rights Reserved.                                     |*/
  15. /*|                                                              |*/
  16. /*[]------------------------------------------------------------[]*/
  17.  
  18.  
  19. #pragma inline
  20. #include <string.h>
  21. #include <asmrules.h>
  22. #include <stdlib.h>
  23.  
  24. extern  char            **environ;
  25. extern  unsigned        _envSize;
  26.  
  27. /*-----------------------------------------------------------------------*
  28.  
  29. Name            putenv - adds string to current environment
  30.  
  31. Usage           int putenv(const char *envvar);
  32.  
  33. Prototype in    stdlib.h
  34.  
  35. Description     Define an environment string to be of the form:
  36.  
  37.                         name=string\0
  38.  
  39.                 This function scans the environment looking for an existing
  40.                 string with the same name as the argument *envvar. If it is
  41.                 found then the pointer envvar  is substituted in the table.
  42.                 The replaced string  is not overwritten or freed,  just the
  43.                 reference to it in the environment table is removed.
  44.  
  45.                 If the argument  represents a new name, not  matched in the
  46.                 existing  environment,  then  it  will  be  appended to the
  47.                 environment  table. The  table is  adjusted in  chunks of 4
  48.                 pointers and is initialized with  at least 4 spare entries,
  49.                 but if all spare entries in the table have been used then a
  50.                 new larger  block is allocated.  The environment is  copied
  51.                 into the new  block, the "environ" pointer is  updated, and
  52.                 the old block is deallocated. The envp parameter to  main()
  53.                 will then be invalid.
  54.  
  55.                 The string  comparison is case-sensitive, in  the usual "C"
  56.                 tradition.
  57.  
  58.  
  59. Return value    On success, putenv returns 0; on failure, -1
  60.  
  61. *------------------------------------------------------------------------*/
  62. int putenv( const char *nameP )
  63.   {
  64.   char  **envP;
  65.  
  66.   nameP = strdup( nameP );           /* ensure that storage is static */
  67.   if( !nameP )  goto BadPutEnvExit;
  68.  
  69.         /* Compute nameP length and remember first character */
  70. asm     LES_    di, nameP
  71. #if (LDATA)
  72. asm     mov     ax, ES
  73. asm     or      ax, di
  74. #else
  75. asm     push    ds
  76. asm     pop     es
  77. asm     or      di, di
  78. #endif
  79. asm     jz      BadPutEnvExit
  80. asm     mov     ah, ES_ [di]
  81. asm     mov     al, '='
  82. asm     mov     cx, -1
  83. asm     cld
  84. asm     repne   scasb
  85. asm     not     cx
  86. asm     dec     cx
  87. asm     jz      BadPutEnvExit   /* CX = VarName length */
  88.  
  89.         /* Look for nameP in environment array */
  90. #if __HUGE__
  91. asm     mov     di, seg environ
  92. asm     mov     DS, di
  93. #endif
  94. asm     LES_    di, DPTR_(environ)
  95. #if (LDATA)
  96. asm     mov     W1 (envP), ES
  97. asm     mov     bx, ES
  98. asm     or      bx, di
  99. #else
  100. asm     or      di, di
  101. #endif
  102. asm     mov     W0 (envP), di
  103. asm     jnz     FirstVariable
  104.  
  105.         /* If no match can be found, return -1. */
  106. BadPutEnvExit:
  107.   free( (void *)nameP );
  108.  
  109. asm     mov     ax, -1
  110. asm     jmp     PutEnvExit
  111.  
  112.                 /* Does the first character match ??? */
  113. NextVariable:
  114. asm     add     W0 (envP), dPtrSize
  115. asm     LES_    di, envP
  116. FirstVariable:
  117. asm     LES_    di, ES_ [di]
  118. #if (LDATA)
  119. asm     mov     bx, ES
  120. asm     or      bx, di
  121. #else
  122. asm     or      di, di
  123. #endif
  124. asm     jz      VarNotFound
  125. asm     mov     al, ES_ [di]
  126. asm     or      al, al          /* "" terminates environment */
  127. asm     jz      VarNotFound
  128. asm     cmp     ah, al          /* compare first characters */
  129. asm     jne     NextVariable
  130. asm     mov     bx, cx
  131. asm     cmp     BY0 (ES_ [di+bx]), '='
  132. asm     jne     NextVariable    /* must be followed by '=' */
  133.  
  134.                 /* Yes, so compare the remainder of nameP */
  135.         pushDS_
  136. asm     LDS_    si, nameP
  137. asm     repe    cmpsb
  138.         popDS_
  139. asm     xchg    cx, bx
  140. asm     jne     NextVariable
  141.  
  142. /* The entries match names.  Replace the old pointer with the new. */
  143. VarFound:
  144. asm     LES_    di, envP
  145. asm     mov     ax, W0 (nameP)
  146. asm     mov     W0 (ES_ [di]), ax
  147. #if (LDATA)
  148. asm     mov     ax, W1 (nameP)
  149. asm     mov     W1 (ES_ [di]), ax
  150. #endif
  151. asm     jmp     short   GoodPutEnvExit
  152.  
  153. /* If arrived here then no matching name exists in the table.  A new */
  154. /*       entry must be made.  Is the existing table big enough ?     */
  155. VarNotFound:
  156. asm     mov     bx, W0(envP)
  157. asm     sub     bx, W0(environ)
  158. asm     add     bx, dPtrSize
  159. asm     cmp     bx, _envSize
  160. asm     jb      Append
  161.  
  162. /* The environment table is full.  It must be enlarged by copying to */
  163. /*       a new memory block.                                         */
  164. asm     add     bx, 4 * dPtrSize
  165. asm     push    bx
  166. asm     call    EXTPROC(malloc)
  167. asm     pop     cx
  168. asm     mov     di, ax
  169. #if (LDATA)
  170. asm     mov     ES, dx
  171. asm     mov     bx, ax
  172. asm     or      bx, dx
  173. #else
  174. asm     push    DS
  175. asm     pop     ES
  176. asm     or      di, di
  177. #endif
  178. asm     jz      BadPutEnvExit
  179. asm     xchg    cx, _envSize
  180. asm     push    cx
  181.         pushDS_
  182. asm     LDS_    si, DPTR_(environ)
  183. asm     rep     movsb
  184.         popDS_
  185. asm     xchg    ax, W0 (environ)
  186. #if (LDATA)
  187. asm     xchg    dx, W1 (environ)
  188. asm     push    dx
  189. #endif
  190. asm     push    ax
  191. asm     call    EXTPROC(free)
  192. asm     add     sp, dPtrSize
  193. asm     pop     bx
  194.  
  195. /* If arrived here then BX points to the first unused table slot  */
  196. /*       and the new entry is to be appended.  The append is done */
  197. /*       by copying the final pointer (to the empty string) up    */
  198. /*       one place and inserting the new string in its place.     */
  199. Append:
  200. asm     LES_    di, DPTR_(environ)
  201. asm     mov     ax, W0 (nameP)
  202. asm     xchg    ax, W0 (ES_ [di+bx-dPtrSize])
  203. asm     mov     W0 (ES_ [di+bx]), ax
  204. #if (LDATA)
  205. asm     mov     ax, W1 (nameP)
  206. asm     xchg    ax, W1 (ES_ [di+bx-dPtrSize])
  207. asm     mov     W1 (ES_ [di+bx]), ax
  208. #endif
  209.  
  210. GoodPutEnvExit:
  211. asm     xor     ax, ax
  212. PutEnvExit:
  213.         return(_AX);
  214. }
  215.