@@ -32,6 +32,27 @@ 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+ return putenv2 (name, value[0 .. strlen(value)]);
44+ }
45+ int putenv2 (const char [] name, const char [] value)
46+ {
47+ auto fullLength = name.length + 1 + value.length;
48+ auto buffer = cast (char * )alloca(fullLength + 1 );
49+ buffer[0 .. name.length] = name[];
50+ buffer[name.length] = ' =' ;
51+ buffer[name.length + 1 .. fullLength ] = value[];
52+ buffer[fullLength] = ' \0 ' ;
53+ return putenv (buffer);
54+ }
55+
3556version (CRuntime_Microsoft )
3657{
3758 // until the new windows bindings are available when building dmd.
@@ -151,6 +172,37 @@ version (Posix)
151172 }
152173}
153174
175+ /**
176+ Use to restore an environment variable when this structure goes out of scope.
177+ */
178+ struct EnvRestore (string varName)
179+ {
180+ private string _saved;
181+ private bool restore;
182+
183+ /**
184+ Access the saved environment variable value.
185+ */
186+ string saved () const { return _saved; }
187+
188+ /**
189+ Call before the overriding the environment variable to save and restore it later.
190+ */
191+ void saveToRestoreLater ()
192+ {
193+ _saved = getenv2(varName);
194+ restore = true ;
195+ }
196+
197+ ~this ()
198+ {
199+ if (restore)
200+ {
201+ putenv2(varName, _saved);
202+ }
203+ }
204+ }
205+
154206/* ****************************
155207 * Run the linker. Return status of execution.
156208 */
@@ -264,8 +316,9 @@ public int runLINK()
264316 const (char )* linkcmd = getenv(global.params.is64bit ? " LINKCMD64" : " LINKCMD" );
265317 if (! linkcmd)
266318 linkcmd = getenv(" LINKCMD" ); // backward compatible
319+ auto restorePATH = EnvRestore! " PATH" ();
267320 if (! linkcmd)
268- linkcmd = vsopt.linkerPath(global.params.is64bit);
321+ linkcmd = vsopt.linkerPath(global.params.is64bit, restorePATH );
269322
270323 int status = executecmd(linkcmd, p);
271324 if (lnkfilename)
@@ -738,15 +791,16 @@ version (Windows)
738791 {
739792 int status;
740793 size_t len;
794+ auto restore_CMDLINE = EnvRestore! " _CMDLINE" ();
795+
741796 if (global.params.verbose)
742797 message(" %s %s" , cmd, args);
743798 if (! global.params.mscoff)
744799 {
745800 if ((len = strlen(args)) > 255 )
746801 {
747- char * q = cast (char * )alloca(8 + len + 1 );
748- sprintf(q, " _CMDLINE=%s" , args);
749- status = putenv(q);
802+ restore_CMDLINE.saveToRestoreLater();
803+ int status = putenv2(" _CMDLINE" , args);
750804 if (status == 0 )
751805 {
752806 args = " @_CMDLINE" ;
@@ -1018,7 +1072,7 @@ version (Windows)
10181072 * Returns:
10191073 * absolute path to link.exe, just "link.exe" if not found
10201074 */
1021- const (char )* linkerPath (bool x64)
1075+ const (char )* linkerPath (bool x64, ref EnvRestore ! " PATH " restorePATH )
10221076 {
10231077 const (char )* addpath;
10241078 if (auto p = getVCBinDir(x64, addpath))
@@ -1030,15 +1084,15 @@ version (Windows)
10301084 {
10311085 // debug info needs DLLs from $(VSInstallDir)\Common7\IDE for most linker versions
10321086 // so prepend it too the PATH environment variable
1033- const char * path = getenv( " PATH " );
1034- const pathlen = strlen(path) ;
1087+ restorePATH.saveToRestoreLater( );
1088+ const char [] path = restorePATH.saved ;
10351089 const addpathlen = strlen(addpath);
10361090
1037- char * npath = cast (char * )mem.xmalloc(5 + pathlen + 1 + addpathlen + 1 );
1091+ char * npath = cast (char * )mem.xmalloc(5 + path.length + 1 + addpathlen + 1 );
10381092 memcpy(npath, " PATH=" .ptr, 5 );
10391093 memcpy(npath + 5 , addpath, addpathlen);
10401094 npath[5 + addpathlen] = ' ;' ;
1041- memcpy(npath + 5 + addpathlen + 1 , path, pathlen + 1 );
1095+ memcpy(npath + 5 + addpathlen + 1 , path.ptr, path.length + 1 );
10421096 putenv(npath);
10431097 }
10441098 return cmdbuf.extractString();
0 commit comments