This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: compiling C w/cygwin vs. -mno-cygwin & dealing with win32


Brian Dessent wrote:
So cygwin pays attention, and my re-passing the args via "execv"
preserves the quoting of filenames, but the no-cyg version appears
to take the argv[1..#] arguments and merge them into 1 argument.
To do the same in the no-cyg version, I'd have to peel each arg
off, put quotes around it, then call execv with everything requoted.

Or just link your MinGW version with the MinGW -lexecwrap library.
---
	This is part of my prob.  I thought the mingw libraries were
automatically selected in place of cygwin libs, I wasn't aware
that the mswin libs had 'execv' (and, really, they sorta don't -- at
least not with the argument-grouping-preserving feature I was
expecting).   Uh oh.... I don't seem to see an execwrap lib on
my system -- and it does not appear to be in the mingw libs
available w/cygwin.....*sigh*...sorry, didn't know such a
separate library (or libraries) were available with mingw.
I don't see a list of libraries referenced on the main mingw site..



So you are saying that when I call execv in cygwin, it...
Not quite. What Cygwin does depends on whether it's exec()ing a Cygwin
binary or a non-Cygwin binary.
---
	Ah Ha!  (*4-watt nightlight bulb turns on in head*).  I
wasn't aware that it examined the binaries before executing them.
No wonder process creates in cygwin are a bit slower than one might
'guess'...this explains a fair bit right there.



#include <windows.h> #include <stdio.h>

int WINAPI
WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
{
  puts ("Hello world.");
  return 0;
}
---
	Ug...that's vaguely familiar...Ug.  Now I remember why I
didn't like Windows programming...it's own special API and
notation...all that hungarian notation...sigh.  But thanks for
the uncomfortable refresher (I really did force myself to take
a class on Win32 programming at one point, but it was probably
10 years ago, and I never made use of it...so...either the pointer
to it were lost on the stack, or just bit-rotted -- the content might
even have been recycled by garbage collection  ...no...not windows
programming information; never that...*cough*).

You can compile this both with Cygwin and MinGW and it will work fine. Note that the parameters passed to the program are nothing like the C
argc/argv. lpCmd is a pointer to a null terminated string containing
the command line, there is no array of arguments anywhere.
---
	Yeah...I remember that [vaguely] from MS-DOS programming days
writing in PL/M and assembler.  C was more 'comfortable' when it came
out for DOS...


It's execv that's falling down, not doing it's job.  My arguments
are already parsed and separated, but the no-cyg version of execv
is mushing them all back together, while cygwin invokes the
next program, apparently with quotes of some sort, around the
contents of each, separate, argv[] string.

It would not be the first time that someone found MSVCRT less than adequate. Again, the MinGW project has a convenient set of wrappers for just this reason.

Isn't MSVCRT the startup code?

No, it's just the opposite: it is the C library minus the startup code.
---
	Wrong anacronym.  Was thinking about "crt0.xxx" on *nix systems.
MSVCRT: Visual C Runtime probably...


And whose implementation of execv() do you think that is exactly? It's
not Cygwin's. It's not MinGW's.
---
	A confusion on my part.  I'm confusing -mno-cygwin with
mingw, sorta -- i.e. I thought it automatically pulled in mingw
libs which in a few cases, I thought, were wrapper functions for
windows functions, and in other cases, just the proper header files
to pull things in from MS's DLL's.  I think I'm missing the mingw
library part, sorry for my 'illusionment' (or misillusionment) (versus
being disillusioned completely on being confronted with reality, but
that an allusion to another topic).


No, that's what I've been trying to say the whole time -- MS's exec()
doesn't do any quoting.
---
	Got it -- MS never does anything compatible if they can help
it -- should have known it was part of their 'Embrace', 'extend',
'extinguish'...appear to embrace standard *nix C calls, extend them
by helpfully ignoring the separation that was 'encoded' into the
argv vector so you can have one homogeneous command line, and then
extinguish it's use on MS, because it's broken...got it (I too often
forget about the machevellian machinations that various entities
go through to enforce their particular agenda).


        Since I'm not forking -- I'm exec'ing, the redirector should
cease to exist (exit), but under cygwin, it does not.  That seems more
of a bug in the cygwin implementation, no?

Sigh. No. Aaaaaargh!


The *whole* *point* of making the wrapper a MinGW app is so that it will
exit and the the thing its wrapping will appear to run in the
background.  This is because the defintion of exec() for a native
program is spawn+exit.  The waiting parent will see that the child has
terminated and continue.
---
	Uh...yeah.  Forgot to mention the part of my having it
not spawn & exit so a parent will wait -- since that's what window's
expects -- otherwise programs that spawn editors won't know when the
editor is "done" and when the calling programs can "collect" the edited
file.  My main point of the redirector was just to change the pathname
that gvim thinks it was invoked by, yet have the benefits of it
being in the "system32" dir of being in the default place to look
for programs so 'every place' that calls gvim, doesn't have to encode
the pathname to the specific install dir (which is different for
each vim install/release).  I don't invoke 'gvim' from bash often
enough to worry about the need for "&" and if I did, an alias (or
shell function) would work as you suggested.


exec() for a Cygwin program means replace, not spawn+exit, as per the
*nix semantics.
---
	Yeah...it's only on a gross level that I was thinking they were
the same ... sorry, I too easily forget such common (though not
unimportant!) details that exec means it is exec'ed within the
same process.

A parent that is waiting on a child is waiting for it
to terminate, which the POSIX exec() most certainly is not.  A child
that has exec()d is still that same child, it is the same process, same
PID, etc.  Please go back and read that lengthy description of the
differences between Win32 exec() and POSIX exec() that I typed out
several messages back because this is exactly the aspect in which they
are different, and Cygwin goes to great pains to make that distinction.
---
	Main one being that win32 doesn't support running a new
program over the top of a currently existing program in the same
PID.  If it was 'necessary' to solving the problem (like I needed
it to be the same PID, I'd remember it as I thought it through
(or wrote the code to implement it).  And...as it turns out..
I need it to in this case -- since I need the default case to be
that gvim doesn't execute in background (for reasons mentioned
above).

	For my needs, I think the easiest solution might be a
cygwin-prog that forks, execs and waits for the child (gvim) to
exit...but it would be a high overhead solution since most of
the cygwin-machinery isn't needed.  However, there's still that
worrisome 'fork' problem I ran into which will likely crop up
again, randomly, and may very well have something to do with something
difficult-to-fix, like Windows memory fragmentation -- which
appears to be far more problematic on Windows than it is on linux.

	I 'think' what might work for most circumstances, be to
run a cygwin program that forks and execs the process and waits for
the child to end.  But there's that 'fork' bug that's going to crop
up 'randomly' likely something to with something I have little control
over -- like Windows memory fragmentation.


If you wanted your wrapper to be a Cygwin wrapper you'd have to fork()
and exec() which is where this whole mess started, which is why I
suggested using a *MINGW* wrapper because it could simply exec().  That
doesn't mean the Cygwin wrapper doesn't have to fork().  In essence a
Cygwin wrapper that only calls exec() is a big no-op, the parent will
still be waiting on the wrapped program to terminate, even though there
has been an extra process thrown in there.
----
	Right -- which isn't _exactly_ what I want due to the
Shell-window popping up.  Probably the most efficient would be a
Mingw program using something like 'spawn' without a 'no-wait' flag.
Hmmm....*and*, not using 'main', since, it seems, that will strip
out quoting and put separately quoted args into separate argv members,
but  instead use a window's 'main' that gets the entire unparsed
command line, and then can just "re-pass" it to the windows-gvim prog.


Curious, BTW, since cygwin 'knows' whether or not it is calling a windows or non-windows program, does it perform "re-window-ification" of command line args that appear to be filenames?

	I'm assuming it does it for at least some ENV vars, since
PATH would have be put back into a Windows compatible form for
called windows programs to know what to make of it.  Sure seems
like cygwin has to jump through random hoops to try to create
sanity (from a *nix/posix perspective) out of the [relative] insanity
of windows...

*sigh*
(being grateful to cygwin team for going through this torture in
the first place; ...)




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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]