delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2011/06/28/00:59:57

X-Recipient: archive-cygwin AT delorie DOT com
X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,RCVD_IN_DNSWL_LOW,TW_RX,TW_YG
X-Spam-Check-By: sourceware.org
Message-ID: <4E095FA3.8030503@cwilson.fastmail.fm>
Date: Tue, 28 Jun 2011 00:59:15 -0400
From: Charles Wilson <cygwin AT cwilson DOT fastmail DOT fm>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.23) Gecko/20090812 Thunderbird/2.0.0.23 Mnenhy/0.7.6.666
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: Re: Strange cygpath behavior.
References: <73619422 DOT 20110621092310 AT mtu-net DOT ru> <4E00321A DOT 30105 AT lysator DOT liu DOT se> <92658329 DOT 20110623165230 AT mtu-net DOT ru> <4E03492D DOT 40109 AT gmail DOT com> <1144668147 DOT 20110623190534 AT mtu-net DOT ru> <4E035F46 DOT 7000207 AT gmail DOT com> <1291997550 DOT 20110623220605 AT mtu-net DOT ru> <4E063FBF DOT 8040103 AT lysator DOT liu DOT se> <48666308 DOT 20110626195750 AT mtu-net DOT ru> <4E07A11F DOT 4050405 AT lysator DOT liu DOT se> <547025238 DOT 20110627173839 AT mtu-net DOT ru>
In-Reply-To: <547025238.20110627173839@mtu-net.ru>
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

On 6/27/2011 9:38 AM, Andrey Repin wrote:
>> As you are apparently using the cmd "shell", the correct way to quote
>> arguments in order to preserve spaces etc, is to use double quotes
>> and escape all backslashes with an extra backslash.
> 
> Ok, please explain, how could I escape backslashes in, say, Explorer?
> It could only quote the string.
> I can't even write my own conversion utility :/
> No amount of external conversion would help using diff or patch freely.

Well, here's the thing: on win32, GUI apps (those compiled for the GUI
subsystem) have a different "entry point" than command line ones (those
compiled for the CUI subsystem.

The GUI ones actually use 'WinMain' as an entry point, while the CUI
ones follow the tradition 'int main(int argc, char * argv[])' entry
point (actually, thanks to a quirk of the C, it is
	int main(int argc, char * argv[], char * envp[])
but usually the third argument is null).

Anyway, since the signature of WinMain is
	int CALLBACK WinMain(
	  __in  HINSTANCE hInstance,
	  __in  HINSTANCE hPrevInstance,
	  __in  LPSTR lpCmdLine,
	  __in  int nCmdShow
	);
the "command line arguments" are passed in as one giant command line,
and parsing it is up the program itself.



Now, *cygwin* programs are usually CUI, but their actual entry point is
mainCRTStartup, regardless of whether they are compiled for the CUI or
GUI subsystem. This function is defined in cygwin1.dll; it does a lot of
stuff, but eventually converts the "big cmd line string" to an argv[]
array, and calls the user's main() function.  This process of converting
"the big cmd line string" is done according to *unix* quoting rules.

There's also a 'stub' main() that does the opposite: if your app defines
a WinMain but no main(), then the stub main gets the "big cmd line
string" via GetCommandLine (e.g. it ignores whatever argv[] was passed
in) and invokes your WinMain using that big string.

See
http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/how-startup-shutdown-works.txt?rev=1.1&content-type=text/x-cvsweb-markup&cvsroot=src

for more info.


So, what's the point?

I think ONE way of solving your problem is to write a wrapper program,
that will *ignore* argv[].  It should grab the full cmd line using
GetCommandLine(), properly quote it using *win32* quoting rules -- and
then invoke the cygwin program you want to run (*) using main(argc,
argv).  Then, cygwin's parsing routines will Do The Right Thing for you.

Here's some code to get you started:
http://sourceforge.net/projects/mingw/files/UserContributed/execwrap/Current%20Release_%20mingw-execwrap-1.0/

(*) In order to bypass the cygwin parsing rules, this wrapper program
should be a native (that is, non cygwin) application.


Now, why is this so hard?

Well, you've got to realize, what you are trying to do is WAY outside
the normal usage pattern for cygwin tools.  In general, we try to make
sure that cygwin tools work "in the unix way" -- and often, that means
they need to be invoked via a unix style shell.  Sometimes, invoking
directly from the Win32 GUI point-n-click arena just doesn't work as
expected -- as you have discovered.

That's why so few cygwin apps install GUI-style shortcuts into the Start
Menu.  If you look, most of the one that do fall into three categories:
(1) shells - like Cygwin.bat or bash (2) terminals, like rxvt or mintty
(3) X apps that take no cmd line arguments.

--
Chuck

--
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

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019