@@ -32,6 +32,23 @@ version (Windows) extern (C) int putenv(const char*);
3232version (Windows ) extern (C ) int spawnlp(int , const char * , const char * , const char * , const char * );
3333version (Windows ) extern (C ) int spawnl(int , const char * , const char * , const char * , const char * );
3434version (Windows ) extern (C ) int spawnv(int , const char * , const char ** );
35+
36+ string getenv2 (const (char )* name)
37+ {
38+ auto result = getenv(name);
39+ return cast (string )result[0 .. strlen(result)];
40+ }
41+ int putenv2 (const char [] name, const char [] value)
42+ {
43+ auto fullLength = name.length + 1 + value.length;
44+ auto buffer = cast (char * )alloca(fullLength + 1 );
45+ buffer[0 .. name.length] = name[];
46+ buffer[name.length] = ' =' ;
47+ buffer[name.length + 1 .. fullLength ] = value[];
48+ buffer[fullLength] = ' \0 ' ;
49+ return putenv (buffer);
50+ }
51+
3552version (CRuntime_Microsoft )
3653{
3754 // until the new windows bindings are available when building dmd.
@@ -151,6 +168,37 @@ version (Posix)
151168 }
152169}
153170
171+ /**
172+ Use to restore an environment variable when this structure goes out of scope.
173+ */
174+ struct EnvRestore (string varName)
175+ {
176+ private string _saved;
177+ private bool restore;
178+
179+ /**
180+ Access the saved environment variable value.
181+ */
182+ string saved () const { return _saved; }
183+
184+ /**
185+ Call before the overriding the environment variable to save and restore it later.
186+ */
187+ void saveToRestoreLater ()
188+ {
189+ _saved = getenv2(varName);
190+ restore = true ;
191+ }
192+
193+ ~this ()
194+ {
195+ if (restore)
196+ {
197+ putenv2(varName, _saved);
198+ }
199+ }
200+ }
201+
154202/* ****************************
155203 * Run the linker. Return status of execution.
156204 */
@@ -264,8 +312,9 @@ public int runLINK()
264312 const (char )* linkcmd = getenv(global.params.is64bit ? " LINKCMD64" : " LINKCMD" );
265313 if (! linkcmd)
266314 linkcmd = getenv(" LINKCMD" ); // backward compatible
315+ restorePATH = EnvRestore! " PATH" ;
267316 if (! linkcmd)
268- linkcmd = vsopt.linkerPath(global.params.is64bit);
317+ linkcmd = vsopt.linkerPath(global.params.is64bit, restorePATH );
269318
270319 int status = executecmd(linkcmd, p);
271320 if (lnkfilename)
@@ -738,15 +787,16 @@ version (Windows)
738787 {
739788 int status;
740789 size_t len;
790+ auto restore_CMDLINE = EnvRestore! " _CMDLINE" ;
791+
741792 if (global.params.verbose)
742793 message(" %s %s" , cmd, args);
743794 if (! global.params.mscoff)
744795 {
745796 if ((len = strlen(args)) > 255 )
746797 {
747- char * q = cast (char * )alloca(8 + len + 1 );
748- sprintf(q, " _CMDLINE=%s" , args);
749- status = putenv(q);
798+ restore_CMDLINE.saveToRestoreLater();
799+ int status = putenv2(" _CMDLINE" , args);
750800 if (status == 0 )
751801 {
752802 args = " @_CMDLINE" ;
@@ -1018,7 +1068,7 @@ version (Windows)
10181068 * Returns:
10191069 * absolute path to link.exe, just "link.exe" if not found
10201070 */
1021- const (char )* linkerPath (bool x64)
1071+ const (char )* linkerPath (bool x64, ref EnvRestore ! " PATH " restorePATH )
10221072 {
10231073 const (char )* addpath;
10241074 if (auto p = getVCBinDir(x64, addpath))
@@ -1030,15 +1080,15 @@ version (Windows)
10301080 {
10311081 // debug info needs DLLs from $(VSInstallDir)\Common7\IDE for most linker versions
10321082 // so prepend it too the PATH environment variable
1033- const char * path = getenv( " PATH " );
1034- const pathlen = strlen(path) ;
1083+ restorePATH.saveToRestoreLater( );
1084+ const char [] path = restorePATH.saved ;
10351085 const addpathlen = strlen(addpath);
10361086
1037- char * npath = cast (char * )mem.xmalloc(5 + pathlen + 1 + addpathlen + 1 );
1087+ char * npath = cast (char * )mem.xmalloc(5 + path.length + 1 + addpathlen + 1 );
10381088 memcpy(npath, " PATH=" .ptr, 5 );
10391089 memcpy(npath + 5 , addpath, addpathlen);
10401090 npath[5 + addpathlen] = ' ;' ;
1041- memcpy(npath + 5 + addpathlen + 1 , path, pathlen + 1 );
1091+ memcpy(npath + 5 + addpathlen + 1 , path.ptr, path.length + 1 );
10421092 putenv(npath);
10431093 }
10441094 return cmdbuf.extractString();
0 commit comments