Subject: Re: CreateProcess() - executed program gets different argument depending if it's compiled with gcc (cygwin) or cl (VS)?
From: Ilguiz Latypov <[email-masked]>
To: [email-masked]
Cc: Piotr Krukowiecki <[email-masked]>
Date: Thu, 18 Feb 2010 19:22:26 -0800 (PST)
List-Id: <cygwin.cygwin.com>

> As you can see dumpargs_gcc receives "\127.0.0.127\foo.cxx" and dumpargs_cl receives "\\127.0.0.127\foo.cxx".

Interesting.  I am confused, too.

(1) Native-only parameter passing:

  execv(PROG, ARGV)  ->  MSVCRT  ->  line = M(ARGV)  ->  CreateProcess( PROG, line, .. )  -> 

           MSVCRT ->  CommandLineToArgvW( line ) -> argv, argc = M'( line )  ->  int main( int argc, char *argv[] )

  http://msdn.microsoft.com/en-us/library/17w5ykft.aspx

(2) POSIX compatibility wrapper (Cygwin):

  execv(PROG, ARGV)  ->  Cygwin DLL  ->  prog = W(PROG), line = C(ARGV)  ->  CreateProcess( prog, line, .. )

       (a) PROG is a native program:

              ->  MSVCRT  ->  CommandLineToArgvW( line )  -> argc, argv = M'( line )  -> int main( int argc, char *argv[] )

       (b) PROG is another Cygwin-linked program:

              ->  Cygwin stub (crt0?)  -> argc, argv = C'( line ) ->  int main( int argc, char *argv[] )

Thanks to your createprocess.c/dumpargs.c pair, I could figure the existing Cygwin's parsing without looking into its source code.  It turned to ignore the escaping power of a bare (unquoted) backslash when it was followed by a double quote, which is against both MSVC and Bash rules.

Here is my understanding of expansion features of Win32 (M), Bash (B) and Cygwin (C) shown as a diagram, where "special character" means a dollar sign [$], a double quote ["], another backslash [\], backquote [`] or a newline, as explained in section 2.2.3 Double-Quotes of the Open Group's XCU document.

  http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html

        Bare backslashes   Bare backslashes     Quoted backslashes     Quoted backslashes
        not followed by a  followed by a        not followed by a      followed by a
        double quote       double quote         special character      special character

 MSVC   regular            protecting           regular                regular
 
 Bash   protecting         protecting           regular                protecting

 Cygwin regular            protecting           regular                protecting

So I guess the confusion remains as to why (a) C != M and (b) C != B.

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple