Subject: Re: [[email-masked]: VC checkin failure]

From: Andrew Innes <[email-masked]>
Date: Fri, 26 Jul 1996 15:55:29 +0100

On Thu, 25 Jul 1996 21:02:27 -0700 (PDT), [email-masked] (Geoff Voelker) said:
>The short story then is that sometimes we want arguments quoted (when
>they truly are arguments with whitespace in them) and at other times
>we don't (when they are entire commands and arguments concatenated
>together into one string but separated by whitespace), and it is not
>obvious how to distinguish these cases inside Emacs.  If arguments to
>commands were always broken up into argv components by the time it
>reaches child_setup (e.g., the grep command, even though an argument
>to the shell, would be broken up into its components, too), then I
>think we could safely set win32-quote-process-args to t by default.
>But this seems impossible to ensure.

Thinking about it from the Unix perspective, the argv array given to
child_setup is already correct because the shell expects a single arg
containing the entire command following -c, which it will interpret as
if it was typed in at the command line and so construct the proper argv
array for grep.

If the standard shell on NT had a sufficiently powerful quoting and
escaping syntax, as the Unix shells do, then this would work on NT as
well even though we have to flatten the array into a single string - any
quoting in the original command arg could be passed through to the shell
by proper escaping.

As it is now, for shell commands the correct behaviour is to have
win32-quote-process-args turned off, because cmd.exe will interpret the
rest of its command line (after consuming things it believes are command
switches for it) as a command line typed by the user.  (When using a
different shell, though, the rule might well be different.)

When starting other processes directly, usually the right thing is to
have win32-quote-process-args enabled - we have to assume that the
caller has constructed the argv array as they intend the subprocess to
see it (if they haven't, then things would fail on Unix), so in this
case, Emacs should quote the args as necessary to ensure the subprocess
reconstructs the args as intended.  In general this isn't possible
because there is no standard or universally used convention for parsing
the command line, but most of the time putting double quotes around an
arg if it contains spaces is correct.

It would have been nice if all places in lisp code which run commmands
via a shell process used shell-command or shell-command-on-region (so we
could set win32-quote-process-args there), but a quick perusal of the
lisp dir shows lots of examples where code does

   (call-process shell-file-name ... "-c" args)

or similar things.  It is too much to expect all packages to go through
the shell-command interface, so we need to deal with this at a lower
level than shell-command.

[One possibility: If we could insist that people use a specific shell on
NT (not cmd.exe), then we could solve the shell command problem that
way.  Or more likely, we would provide a subprocess "helper" application
that NT Emacs always used to invoke whatever program is really intended.
This ends up using extra process resources unnecessarily in many cases.]

>Alternatively, we could have the NT specific code check to see if the
>command it is spawning is the shell (and the second argument is the
>equivalent of "/c"), and have that code automatically break up into
>components the command to be executed in the shell (assuming that
>words that should go together are already quoted).  Otherwise, we
>would quote any arguments with whitespace in them (that are not
>already quoted).  Andrew, can you think of a case where this wouldn't
>work very well?

No - I think something along these lines will be necessary (and this is
the best suggestion I've seen so far).

However, it occurs to me that we should really provide a way for the
user to specify what kind of quoting behaviour is required in each case.
We know that the correct quoting really depends on which shell program
is being used (and not just shells - some individual programs may
require special handling as well).

I suggest adding a hook or handler mechansim of some sort (to both
start-process and call-process) to allow lisp code to modify the arg
list before it is passed to child_setup.  That way, the lisp code could
implement proper quoting, or splitting of args etc, based on the program
name or whatever criteria was considered appropriate.

This would even allow working with packages that directly call "sh",
"rm", or other Unix-specific programs - if a user wanted to, they could
intercept invocations of specific programs and invoke an appropriate
substitute instead.  In the case of call-process, they might even want
to implement the functionality entirely in lisp (eg. you could imagine
ls-lisp working this way), but this is probably going too far.

Then child_setup et al would not need to worry about this issue -
win32-quote-process-args would go, and sys_spawnve would always simply
concatenate the args together separated by spaces.

Does this sound like a reasonable solution?

AndrewI

---

From: Andrew Innes <[email-masked]>
Date: Fri, 26 Jul 1996 16:52:29 +0100

On Fri, 26 Jul 1996 15:55:29 +0100, Andrew Innes <andrewi> said:
  [ .. ]
>name or whatever criteria was considered appropriate.

An obvious way of adding a "hook" mechansim would be to introduce a
variable `process-name-arg-handler-alist' (say), which relates regexps
(matching on program name) to handler functions that would return the
actual argument list (including the program name) to be used.

If the handler was `t' then "standard" quoting of args with spaces would
be performed; `nil' would mean use the original arg list directly.

There is no reason this mechansim (if accepted) shouldn't be provided
for all platforms, although it is most useful for Windows (and DOS, and
maybe VMS).

AndrewI