This is the mail archive of the
cygwin-patches@cygwin.com
mailing list for the Cygwin project.
Re: [Patch] Loading cygwin1.dll from MinGW and MSVC
On Mon, 6 Jun 2005, Christopher Faylor wrote:
> On Mon, Jun 06, 2005 at 03:40:10PM -0400, Igor Pechtchanski wrote:
> >On Mon, 6 Jun 2005, Christopher Faylor wrote:
> >
> >> I fat fingered my response to Max, ended up sending a personal message
> >> and never noticed until I received a personal reply from him. I, of
> >> course, asked him not to send me personal email which was pretty
> >> confusing since I'd previously just sent him a personal reply.
> >>
> >> Translation: I am a maroon.
> >>
> >> Anywhay this is what should have gone out days ago.
> >>
> >> On Fri, Jun 03, 2005 at 03:58:09PM -0700, Max Kaehn wrote:
> >> >This patch contains the changes to make it possible to dynamically load
> >> >cygwin1.dll from MinGW and MSVC applications. The changes to dcrt0.cc are
> >> >minimal and only affect cygwin_dll_init(). I've also added a MinGW test
> >> >program to testsuite and a FAQ so people will be able to locate the
> >> >test program easily.
> >> >
> >> >I wrote how-cygtls-works.txt because it took me a while to figure out how it
> >> >was storing the information, and I hope I can save someone else the effort in
> >> >the future. (I had no idea Windows was still using segment registers!)
> >> >I hope I got the copyright message right for it.
> >>
> >> Wow! That's great! Thanks for doing this. It is much appreciated. This
> >> is something that I had been meaning to do and you did a better job than
> >> I would have. This truly deserves a gold star. I know that understanding
> >> the cygtls stuff could not have been easy.
> >>
> >> Can I get a gold star over here for this truly heroic effort?
> >
> >One(?) gold star coming up. What's it for, though -- the changes that
> >enable dynamically loading cygwin1.dll, or how-cygtls-works.txt?
>
> For now: how-cygtls-works.txt.
Ok, done. One gold star, freshly minted.
> >>[snip]
> >> Having an interface which requires a "main" function name so that you'd
> >> do something like:
> >>
> >> int
> >> main (int argc, char **argv)
> >> {
> >> initialize_cygwin (rest_of_main, argc, argv);
> >> /* never returns */
> >> }
> >>
> >> int
> >> rest_of_main (argc, argv)
> >> {
> >> /* do main stuff */
> >> .
> >> .
> >> .
> >> exit or return here
> >> }
> >>
> >> And in cygwin initialize_cygwin would look something like:
> >>
> >> void
> >> initialize_cygwin (int (*) main, int argc, char **argv)
> >> {
> >> struct _cygtls dummy_tls;
> >> initialize_main_tls (&dummy_tls);
> >> cygwin_dll_init ();
> >> exit (main (argc, argv));
> >
> >Did you mean "exit (rest_of_main (argc, argv));" here?
>
> No. I meant to use the function that was passed in, i.e. main,
> although maybe it would be safer not to call it "main". This is a DLL
> routine that wouldn't know about rest_of_main.
Ug, that'd teach me to actually read the messages I'm replying to. :-)
> As Max points out, though, this does stand the chance of nuking argv,
> though, so that would have to be copied before before initialize_main_tls was
> called:
>
> i.e., something like (modulo typos):
>
> void
> initialize_cygwin (int (*main) (int argc, char **argv), int argc, char **argv)
> {
> struct _cygtls dummy_tls;
> char *newargv = alloca (argc * sizeof (argv[0]));
> for (char **av = newargv; *av; av++)
> *av = *argv++;
> *av = NULL;
> initialize_main_tls (&dummy_tls);
> cygwin_dll_init ();
> exit (main (argc, newargv));
> }
>
> cgf
I wonder if this could, perhaps, be made more transparent to the
programmer, by introducing a static marker, for example. Something like
(again, modulo typos):
void
initialize_cygwin (int (*main) (int argc, char **argv), int argc, char **argv)
{
static int was_here = 0;
if (was_here) return;
was_here = 1;
struct _cygtls dummy_tls;
char *newargv = alloca (argc * sizeof (argv[0]));
for (char **av = newargv; *av; av++)
*av = *argv++;
*av = NULL;
initialize_main_tls (&dummy_tls);
cygwin_dll_init ();
exit (main (argc, newargv));
}
Then main() could look like this:
int
main (int argc, char **argv)
{
initialize_cygwin (main, argc, argv); /* could return */
/* do main stuff */
.
.
.
exit or return here
}
Or is there a reason for main() to be thread-safe or for
initialize_cygwin() to be called twice?
Igor
--
http://cs.nyu.edu/~pechtcha/
|\ _,,,---,,_ pechtcha@cs.nyu.edu
ZZZzz /,`.-'`' -. ;-;;,_ igor@watson.ibm.com
|,4- ) )-,_. ,\ ( `'-' Igor Pechtchanski, Ph.D.
'---''(_/--' `-'\_) fL a.k.a JaguaR-R-R-r-r-r-.-.-. Meow!
"The Sun will pass between the Earth and the Moon tonight for a total
Lunar eclipse..." -- WCBS Radio Newsbrief, Oct 27 2004, 12:01 pm EDT