[MLton] Re: [MLton-commit] r6699

Matthew Fluet fluet at tti-c.org
Wed Jun 17 12:47:33 PDT 2009


On Wed, 17 Jun 2009, Wesley W. Terpstra wrote:
> On Wed, Jun 17, 2009 at 5:45 PM, Matthew Fluet<fluet at tti-c.org> wrote:
>>  * create {env = NONE, ...} should result in calling CreateProcess with a
>>   NULL lpEnvironment; this is, by far, the most common case I would
>>   think.
>
> Why does this work? I don't understand how a cygwin program can call
> another cygwin program with env = NONE. I would have expected this
> means PATH still has /usr/bin. Unless the environment provided to
> MLton from cygwin is a lie that has been translated from the real
> environment and the real environment is what gets copied by
> CreateProcess.

Cygwin most definitely "lies" when providing the result for 
Posix.ProcEnv.environ.  There seem to be a number of environment variables 
that Cygwin translates between Windows paths and Cygwin paths:

[fluet at winxp-cygwin tmp]$ ./environ.exe | grep TMP
TMP=/cygdrive/c/WINDOWS/TEMP
[fluet at winxp-cygwin tmp]$ cmd.exe /c set | grep TMP
TMP=c:\WINDOWS\TEMP

It also seems that the vast number of environment variables set by Cygwin 
are not replicated into the real environment that is copied by 
CreateProcess with a NULL lpEnvironment.  That is, recall:

[fluet at winxp-cygwin tmp]$ ./parent.exe 'C:\WINDOWS\system32\cmd.exe' 'C:\WINDOWS\system32\cmd.exe /c set'
modname = C:\WINDOWS\system32\cmd.exe
cmdline = C:\WINDOWS\system32\cmd.exe /c set
piProcInfo.hProcess = 1856
COMSPEC=C:\WINDOWS\system32\cmd.exe
PATH=C:\cygwin\home\fluet\bin;...elided...
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS
PROMPT=$P$G
SYSTEMDRIVE=C:
SYSTEMROOT=C:\WINDOWS
WINDIR=C:\WINDOWS
status: 0

and contrast to:

[fluet at winxp-cygwin tmp]$ /cygdrive/c/WINDOWS/system32/cmd.exe /c set
ALLUSERSPROFILE=C:\Documents and Settings\All Users
COMMONPROGRAMFILES=C:\Program Files\Common Files
COMPUTERNAME=WINXP-CYGWIN
...elided...
PATH=C:\cygwin\home\fluet\bin;...elided...
...elided...
TEXMFCONFIG=/home/fluet/share/texmf-config
TEXMFHOME=/home/fluet/share/texmf-local
TMP=c:\WINDOWS\TEMP
...elided...
WINDIR=C:\WINDOWS
WINDOW=4
_=/cygdrive/c/WINDOWS/system32/cmd.exe

The Cygwin spawnv{,p} functions (and presumably the execv{,p} functions) 
seem to replicate the environment variables set by Cygwin (and uncygwinify 
the paths of select variables) and construct an explicit environment (that 
mimics inheritance of the parent environment) for use as lpEnvironment for 
the underling CreateProcess call.  Note that invoking 'cmd.exe /c set' 
from the bash shell has loads of variables, and the TEXMFCONFIG and 
TEXMFHOME paths have been left alone but PATH and TMP are uncygwinified.

The Cygwin spawnv{,p}e functions only replicate the given environment 
variables (but do uncygwinify the paths of select variables) and construct 
an explicit environment for use as lpEnvironment for the underlying 
CreateProcess call.  Hence, there is the same PATH/cygwin1.dll problem 
when spawnv{,p}e-ing a Cygwin program --- except that here you need 
'/usr/bin' in PATH (to be uncyginified to 'C:\cygwin\bin')!

> If you set an environment variable in the calling
> cygwin process, does the CreateProcess cygwin child see it?

No.  (Unless you set one of the "special" environment variables: PATH, 
SYSTEMDRIVE, SYSTEMROOT, WINDIR --- and with the exception of PATH, I 
would be wary of mucking with any of the others.)


Another option would be to mimic Cygwin's implementation of spawnv{,p} and 
uncygwinify the paths of select variables from Posix.ProcEnv.eviron; it's 
just not documented which variables.


>>  * create {env = SOME [...], ...} should behave as currently implemented;
>>   the user is responsible for establishing the correct environment (it is
>>   just the case that the correct environment for a Cygwin program is
>>   subtle)
>
> Indeed.
>
> _______________________________________________
> MLton mailing list
> MLton at mlton.org
> http://mlton.org/mailman/listinfo/mlton


More information about the MLton mailing list