Subject: Re: bug#6784: 24.0.50; cmdproxy incosistency with command pathnames

From: Laimonas Vėbra <[email-masked]>
Date: Tue, 03 Aug 2010 23:15:30 +0300

Eli Zaretskii wrote:
>> From: Laimonas Vėbra<[email-masked]>
>> Cc: [email-masked]
>>
>> Óscar Fuentes wrote:
>>
>>> That's one more incosistency: a long command works fine, then you put
>>> that command as part of a pipe chain and it stops working. I guess the
>>> current cmdproxy approach is the lesser evil.
>>
>> It's a CreateProcess() (in cmdproxy.c) _valid_ path requirement/problem;
>> valid path/directory separator is (should be) '\':
>
> But the name of the shell, which is the only file name CreateProcess
> should care about in this case, _is_ converted to use backslashes:

The problem is poor CreateProcess() description and some flawless aspects.
Why do we have to call CreateProcess like this:

  rv = CreateProcess (progname, cmdline, &sec_attrs, NULL, TRUE,
			0, envblock, dir, &si, &child);

where progname is 'cmd.exe' and cmdline is 'cmd.exe /c command'

Somewhere i read, that this way it just works (with less problems).

The problem doesn't occur, when we call CreateProcess() like
this:
CreateProcess ('C:\cygwin\bin\ls.exe', 'C:/cygwin/bin/ls.exe'...)

That's actually the case when we are not invoking a shell (command 
without pipe or redirection), e.g.:
M-x grep
c:/cygwin/bin/ls

Then progname gets correctly backslashed by:
  if (!get_next_token (path, &args))
	  canon_filename (path);
	  progname = make_absolute (path);

My guess is that in this case CreateProcess() takes correctly 
backslashed progname (LPCTSTR lpApplicationName),
as the executable module name (program name), _ignores_ first token of 
cmdline (LPTSTR lpCommandLine) as it is internally treated to be the 
same executable module name (although with wrong slashes) and 
takes/passes remaining tokens of cmdline as command line args of progname.

Actual bug problem arises/occurs, then we are invoking a shell (e.g. 
c:/cygwin/bin/ls | grep foo); then CreateProcess() gets likes this:

CreateProcess('C:\WINDOWS\system32\cmd.exe', 
'"C:\WINDOWS\system32\cmd.exe" /c c:/cygwin/bin/ls | grep foo'...)

I guess, that CreateProcess(), in this case, internally processes 
command line args, i.e. program names/paths ('c:/cygwin/bin/ls', 
'grep'), that it passes to cmd.exe and because command name/path is not 
correctly/appropriately constructed (should be backslashed), it (chain 
CreateProcess()->cmd.exe) fails.