Subject: Re: cmdproxy

From: Andrew Innes <[email-masked]>
Date: Mon, 30 Jun 1997 13:37:50 +0100 (BST)

On Sun, 29 Jun 1997 12:45:46 -0700 (PDT), [email-masked] (Geoff Voelker) said:
>Andrew,
>
>Below is my current version of cmdproxy.c.  I have concentrated so far
>on the case where "-c" is specified on the command line and it can
>execute the specified command directly.  I think that this case is
>done, although you might want to look at it yourself.  I had a couple
>of questions about the other cases, though.

Great, thanks.  I've actually cleaned up some of the other cases myself,
in a spare moment, so our efforts should dovetail nicely.

>When cmdproxy is used as a helper app for DOS programs, how is it that
>argv[0] is not the result of GetModuleFileName, i.e., how is it that
>the following predicate should evaluate to true:
>
>    if (GetModuleFileName (NULL, modname, sizeof (modname)) &&
>	strcmp (modname, argv[0]) != 0)

This question (and the one below) relates to changes I've made to
sys_spawnve in Emacs.  Emacs now detects not only DOS binaries, but also
Win32 applications that have been compiled using the Cygnus gcc port.

When asked to run a DOS program, Emacs now explicitly changes progname
to "cmdproxy.exe" while leaving cmdline unchanged.  Because of an
interesting feature of CreateProcess, Emacs thus starts cmdproxy.exe
even though the command line refers to the DOS program.  cmdproxy can
thus tell it was being invoked in this way, since MSVC sets up argv
purely by parsing the command line.

I did it this way, rather than changing the command line to add "-c",
partly to avoid disturbing the command line in any way (DOS programs are
more likely to interpret their command line in unusual ways), and
because in future cmdproxy might try to do extra things when starting a
DOS program on Windows 95.

>Secondly, when cmdproxy goes through its arguments, it assumes that
>the argv entry following the -c is the command.  But this does not
>seem correct if Emacs is quoting process arguments.  For example, if
>cmdproxy were invoked as
>
>	cmdproxy -c "grep ""some text"" *.c"
>
>then the argv entry after the '-c' is 'grep "some'.  For the case
>where cmdproxy can execute the command directly, I have it parse the
>string returned by GetCommandLine and determine the command itself,
>unquoting the quoting done by Emacs along the way.  But I think that
>this should be done for the case where a real shell has to execute the
>command, too.

This is where another change to sys_spawnve comes in.  By inspecting the
MSVC startup code, I discovered that MSVC uses backslash to escape
embedded quotes.  (Actually, it appears that MSVC intended to allow
quotes to be doubled for the same purpose, but because of a bug, quotes
have to be tripled for this to work!)

However, the Cygnus startup code only recognises doubled quotes.  (I
plan to submit a change to them sometime to allow backslash as an escape
character as well.  For now, this creates an additional barrier to
interoperability between Cygnus apps and "normal" apps.)

So Emacs now changes its quoting rule (by default) according to whether
it thinks the Win32 app is a Cygnus app or not.  If not, backslash is
used for escaping - this happens for cmdproxy, which is why the next
argv entry after "-c" contains the correct command line.

Since the embedded command line passed in this way is often typed
directly by the user, it seemed reasonable for cmdproxy to not make any
attempt to parse it (except to find which program to spawn, if it can do
so directly).  Well, actually it might be useful to parse the embedded
command line (allowing both methods of escaping) and possibly
reconstruct it using the appropriate method as Emacs does.

AndrewI