@@ -734,33 +734,40 @@ static int lookupenv(char **env, const char *name, size_t nmln)
734
734
735
735
/*
736
736
* If name contains '=', then sets the variable, otherwise it unsets it
737
+ * Size includes the terminating NULL. Env must have room for size + 1 entries
738
+ * (in case of insert). Returns the new size. Optionally frees removed entries.
737
739
*/
738
- static char * * do_putenv (char * * env , const char * name , int free_old )
740
+ static int do_putenv (char * * env , const char * name , int size , int free_old )
739
741
{
740
742
char * eq = strchrnul (name , '=' );
741
743
int i = lookupenv (env , name , eq - name );
742
744
743
745
if (i < 0 ) {
744
746
if (* eq ) {
745
- for (i = 0 ; env [i ]; i ++ )
746
- ;
747
- env = xrealloc (env , (i + 2 )* sizeof (* env ));
748
- env [i ] = (char * ) name ;
749
- env [i + 1 ] = NULL ;
747
+ env [size - 1 ] = (char * ) name ;
748
+ env [size ] = NULL ;
749
+ size ++ ;
750
750
}
751
751
}
752
752
else {
753
753
if (free_old )
754
754
free (env [i ]);
755
755
if (* eq )
756
756
env [i ] = (char * ) name ;
757
- else
757
+ else {
758
758
for (; env [i ]; i ++ )
759
759
env [i ] = env [i + 1 ];
760
+ size -- ;
761
+ }
760
762
}
761
- return env ;
763
+ return size ;
762
764
}
763
765
766
+ /* used number of elements of environ array, including terminating NULL */
767
+ static int environ_size = 0 ;
768
+ /* allocated size of environ array, in bytes */
769
+ static int environ_alloc = 0 ;
770
+
764
771
#undef getenv
765
772
char * mingw_getenv (const char * name )
766
773
{
@@ -780,7 +787,8 @@ char *mingw_getenv(const char *name)
780
787
781
788
int mingw_putenv (const char * namevalue )
782
789
{
783
- environ = do_putenv (environ , namevalue , 1 );
790
+ ALLOC_GROW (environ , (environ_size + 1 ) * sizeof (char * ), environ_alloc );
791
+ environ_size = do_putenv (environ , namevalue , environ_size , 1 );
784
792
return 0 ;
785
793
}
786
794
@@ -973,31 +981,28 @@ static char *path_lookup(const char *cmd, char **path, int exe_only)
973
981
static wchar_t * make_environment_block (char * * deltaenv )
974
982
{
975
983
wchar_t * wenvblk = NULL ;
976
- int count = 0 ;
977
- char * * e , * * tmpenv ;
978
- int size = 0 , wenvsz = 0 , wenvpos = 0 ;
984
+ char * * tmpenv ;
985
+ int i = 0 , size = environ_size , wenvsz = 0 , wenvpos = 0 ;
979
986
980
- while (environ [ count ])
981
- count ++ ;
987
+ while (deltaenv && deltaenv [ i ])
988
+ i ++ ;
982
989
983
- /* copy the environment */
984
- tmpenv = xmalloc (sizeof ( * tmpenv ) * ( count + 1 ));
985
- memcpy (tmpenv , environ , sizeof ( * tmpenv ) * ( count + 1 ));
990
+ /* copy the environment, leaving space for changes */
991
+ tmpenv = xmalloc (( size + i ) * sizeof ( char * ));
992
+ memcpy (tmpenv , environ , size * sizeof ( char * ));
986
993
987
994
/* merge supplied environment changes into the temporary environment */
988
- for (e = deltaenv ; e && * e ; e ++ )
989
- tmpenv = do_putenv (tmpenv , * e , 0 );
995
+ for (i = 0 ; deltaenv && deltaenv [ i ]; i ++ )
996
+ size = do_putenv (tmpenv , deltaenv [ i ], size , 0 );
990
997
991
998
/* environment must be sorted */
992
- for (count = 0 ; tmpenv [count ]; )
993
- count ++ ;
994
- qsort (tmpenv , count , sizeof (* tmpenv ), compareenv );
999
+ qsort (tmpenv , size - 1 , sizeof (char * ), compareenv );
995
1000
996
1001
/* create environment block from temporary environment */
997
- for (e = tmpenv ; * e ; e ++ ) {
998
- size = 2 * strlen (* e ) + 2 ; /* +2 for final \0 */
1002
+ for (i = 0 ; tmpenv [ i ]; i ++ ) {
1003
+ size = 2 * strlen (tmpenv [ i ] ) + 2 ; /* +2 for final \0 */
999
1004
ALLOC_GROW (wenvblk , (wenvpos + size ) * sizeof (wchar_t ), wenvsz );
1000
- wenvpos += xutftowcs (& wenvblk [wenvpos ], * e , size ) + 1 ;
1005
+ wenvpos += xutftowcs (& wenvblk [wenvpos ], tmpenv [ i ] , size ) + 1 ;
1001
1006
}
1002
1007
/* add final \0 terminator */
1003
1008
wenvblk [wenvpos ] = 0 ;
@@ -2015,7 +2020,9 @@ void mingw_startup()
2015
2020
maxlen = max (maxlen , wcslen (wenv [i ]));
2016
2021
2017
2022
/* nedmalloc can't free CRT memory, allocate resizable environment list */
2018
- environ = xcalloc (i + 1 , sizeof (char * ));
2023
+ environ = NULL ;
2024
+ environ_size = i + 1 ;
2025
+ ALLOC_GROW (environ , environ_size * sizeof (char * ), environ_alloc );
2019
2026
2020
2027
/* allocate buffer (wchar_t encodes to max 3 UTF-8 bytes) */
2021
2028
maxlen = 3 * maxlen + 1 ;
@@ -2032,6 +2039,7 @@ void mingw_startup()
2032
2039
len = xwcstoutf (buffer , wenv [i ], maxlen );
2033
2040
environ [i ] = xmemdupz (buffer , len );
2034
2041
}
2042
+ environ [i ] = NULL ;
2035
2043
free (buffer );
2036
2044
2037
2045
/* initialize critical section for waitpid pinfo_t list */
0 commit comments