[MLton] Re: [MLton-commit] r6699
Matthew Fluet
fluet at tti-c.org
Tue Jun 16 08:36:33 PDT 2009
On Tue, 16 Jun 2009, Wesley W. Terpstra wrote:
> On Tue, Jun 16, 2009 at 1:13 AM, Matthew Fluet<fluet at tti-c.org> wrote:
>> So, I don't see why it is sensible for Cygwin
>> or MinGW to munge/unmunge arguments at all, since it can't know what
>> was/will-be done on the other end.
>
> Well, I won't debate whether it's sensible, but that is how it works.
> It does seem likely that the string eventually delivered to a
> CreateProcess kernel call is escaped similarly for both cygwin and
> mingw (though as I mentioned, it is possible this is false).
O.k., then what is the rationale for the Basis Library implementation to
add another level of munging on top of that done by Cygwin or MinGW?
> I wouldn't be surprised if the spawn() function on cygwin1.dll
> requires no escaping at all. They're in a position to fix this bug for
> their applications.
My testing seems to support this claim. The
<src>/regression/args-spawn.sml test (renamed from spawn.sml and using
CommandLine.name() to fetch the executable name) works fine, including
when run from a path with spaces and when invoked with a full path (with
spaces).
Of course, this is using a Cygwin program to spawn a Cygwin program (that
happens to be itself); I'm not sure whether this configuration is meant to
support a Cygwin program spawning a Windows CRT program? It seems to:
[fluet at winxp-cygwin tmp]$ cat args-spawn.sml
val cmd = CommandLine.name ()
val _ = print (concat ["cmd: ", cmd, "\n"])
val args = CommandLine.arguments ()
val _ = foldl (fn (arg,()) => print (concat ["arg: ", arg, "\n"])) () args
open Posix.Process
open MLton.Process
val () =
let
val pid = spawn {path = hd args, args = args}
val status = waitpid (W_CHILD pid, [])
in
()
end
[fluet at winxp-cygwin tmp]$ ./args-spawn C:\\Documents\ and\ Settings\\fluet\\My\ Documents\\My\ Programs\\finger.exe -l fluet at ttic.uchicago.edu
cmd: ./args-spawn
arg: C:\Documents and Settings\fluet\My Documents\My Programs\finger.exe
arg: -l
arg: fluet at ttic.uchicago.edu
[nagoya.uchicago.edu]
> Finger: connect::Connection refused
[fluet at winxp-cygwin tmp]$ ./args-spawn /cygdrive/c/Documents\ and\ Settings/fluet/My\ Documents/My\ Programs/finger.exe -l fluet at ttic.uchicago.edu
cmd: ./args-spawn arg: /cygdrive/c/Documents and Settings/fluet/My Documents/My Programs/finger.exe
arg: -l
arg: fluet at ttic.uchicago.edu
[nagoya.uchicago.edu]
> Finger: connect::Connection refused
[fluet at winxp-cygwin tmp]$ ./args-spawn /cygdrive/c/Documents\ and\ Settings/fluet/My\ Documents/My\ Programs/finger.exe '-l fluet at ttic.uchicago.edu'
cmd: ./args-spawn arg: /cygdrive/c/Documents and Settings/fluet/My Documents/My Programs/finger.exe
arg: -l fluet at ttic.uchicago.edu
Displays information about a user on a specified system running the
Finger service. Output varies based on the remote system.
FINGER [-l] [user]@host [...]
-l Displays information in long list format.
user Specifies the user you want information about. Omit the user
parameter to display information about all users on the
specifed host.
@host Specifies the server on the remote system whose users you
want information about.
Note that in the last case, the single argument with an embedded space is
delivered whole to the program, prompting the help listing that is given
on any invalid argument. I also note that the invoked program executes
whether I use finger.exe or finger. This would appear to be handled by
the cygwin1.dll implementation of spawne, since the ML string is passed
unmodified through to the spawne function.
This seems like reasonable behavior for MLton.Process.spawn{,e,p}.
> The CreateProcess will definitely need some sort
> of escaping, though.
Ok, because the CreateProcess function takes a single string for the
arguments, so the munging needs to be done on the ML side. And, the
current claim is that the "default" munging for Cygwin, MinGW, and
(normal) Windows CRT are all different? Or, rather, that there is no
"standard" munging?
In any case, there seems to be a problem with CreateProcess, possibly
independent of the argument munging. The child process seems to to be
created:
[fluet at winxp-cygwin tmp]$ cat args-create.sml
val cmd = CommandLine.name ()
val _ = print (concat ["cmd: ", cmd, "\n"])
val args = CommandLine.arguments ()
val _ = foldl (fn (arg,()) => print (concat ["arg: ", arg, "\n"])) () args
open MLton.Process
val () =
let
val pid =
create {args = tl args,
env = NONE,
path = hd args,
stderr = Param.self,
stdin = Param.self,
stdout = Param.self}
val status = reap pid
in
()
end
[fluet at winxp-cygwin tmp]$ ./args-create 'C:\WINDOWS\system32\finger.exe'
cmd: ./args-create
arg: C:\WINDOWS\system32\finger.exe
unhandled exception: SysErr: No child processes [child]
More information about the MLton
mailing list