public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: "Aaron Digulla" <digulla@hepe.com>
To: "cygwin@cygwin.com" <cygwin@cygwin.com>
Subject: RE: Formatting command line arguments when starting a Cygwin  process from a native process
Date: Tue, 10 May 2016 13:30:00 -0000	[thread overview]
Message-ID: <6533-5731e280-9-60079180@7271027> (raw)
In-Reply-To: <E51C5B015DBD1348A1D85763337FB6D9F04BD207@Remus.metastack.local>


Am Montag, 09. Mai 2016 17:19 CEST, David Allsopp <david@allsopps.net> schrieb:

> Aaron Digulla wrote:
> >
> > Am Samstag, 07. Mai 2016 09:45 CEST, "David Allsopp" <dra27@cantab.net>
> > schrieb:
> >
> >
> > > > Then all you need is a rudimentary quoting.
> > >
> > > Yes, but the question still remains what that rudimentary quoting is -
> > i.e.
> > > I can see how to quote spaces which appear in elements of argv, but I
> > > cannot see how to quote double quotes!
> >
> > This should help:
> > https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/e
> > veryone-quotes-command-line-arguments-the-wrong-way/
>
> This provides documentation for how Microsoft implementations do it, not how Cygwin does it. The Cygwin DLL is responsible for determining how a Cygwin process gets argc and argv from GetCommandLineW.

That's correct but I read your question as "how do I start executables linked against Cygwin from another Windows process"

To do that, you need to convert the argument list/array into the stupid Windows format because that's what the Cygwin process will expect.

> > My line of thought is that Cygwin can't get anything which Windows can't
> > send it. So the first step to solve this mess is to make sure the
> > arguments which you send to CreateProcess() are correct.
> >
> > The next step would be to write a small C utility which dumps it's

> > arguments, so you can properly debug all kinds of characters.
>
> See later email, but IMHO the conversion is something Cygwin should have precisely documented, not determined by brittle experimentation.

Ah... no. You're mixing two or three things. Let me enumerate:

1. You have to give your OS (Windows or Unix) the information which process you want to start and which arguments to pass. Unix has two ways (string array and single string), Windows has only single string.
2. The OS will put the information into a structure of some kind and pass that to the new process.
3. If you have a shell (CMD.exe, bash, etc), they will take the structure and parse it according to some rules. They will then convert the result again into an OS call.
4. The C runtime of your executable will know where to get the OS structure and how to turn the structure into char ** argv.

Where is Cygwin in all this? It's part of step #3. Cygwin emulates exec() and similar Unix OS functions which an emulated shell like BASH will use. Which means Cygwin code in the DLL is irrelevant if you don't have a Unix shell somewhere in your process chain.

If you just want to execute a Cygwin process (= Windows process which includes the Cygwin.dll), you need to know #1, #2 and #4.


> > PS: I always point people to string list/array type methods to create
> > processes which fix all the problems with spaces and odd characters
> > (quotes, umlauts, etc). It seems that Windows doesn't have such a method
> > to create processes. Which kind of makes sense; Windows is very, very
> > mouse centered.
>
> I fail to see the connection with mice! What Windows (NT) does have is a legacy where the decision on how to convert a command line to a list/array of arguments is determined per-process (and so not the responsibility of command line shells) vs Unix which puts the burden of converting a single command line to the array on the shell instead. Nominally, the Windows way is more flexible, though I don't think that flexibility is actually useful (especially if you look at the comments in the command line -> argv conversion in Microsoft's C Runtime library!).

Using single strings to run commands causes all kinds or problems. It's a brittle API, which you should avoid. It kind of feels more simple but it's the "too simple" kind which Einstein mentioned ("You should make things as simple as possible. But not more simle.")

Think of it that way: Your executable gets the arguments as a string array. On the parent process side, Unix allows you to create a process with an array of strings. That's a natural API which doesn't need any kind of conversion (maybe you need to copy the strings but that's it).

If you convert from and to a single string all the time, you need a way to quote and escape. So this is more error prone than the plain array solution.

And lastly: If everyone would always use arrays, we wouldn't have this long, tedious discussion.

Regards,

--
Aaron "Optimizer" Digulla a.k.a. Philmann Dark
"It's not the universe that's limited, it's our imagination.
Follow me and I'll show you something beyond the limits."
http://blog.pdark.de/


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

  reply	other threads:[~2016-05-10 13:30 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-05 15:24 David Allsopp
2016-05-05 16:47 ` Erik Soderquist
2016-05-06  8:03   ` David Allsopp
2016-05-06 13:17     ` Erik Soderquist
2016-05-06 14:35     ` Andrey Repin
2016-05-07  7:45       ` David Allsopp
2016-05-09  9:43         ` Peter Rosin
2016-05-09 10:06           ` Marco Atzeri
2016-05-09 15:49             ` David Allsopp
2016-05-09 16:02               ` Marco Atzeri
2016-05-09 16:14                 ` David Allsopp
2016-05-09 15:49           ` David Allsopp
2016-05-09 14:57         ` Aaron Digulla
2016-05-09 15:19           ` David Allsopp
2016-05-10 13:30             ` Aaron Digulla [this message]
2016-05-10 17:02               ` David Allsopp

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6533-5731e280-9-60079180@7271027 \
    --to=digulla@hepe.com \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).