From: cgf AT cygnus DOT com (Christopher Faylor) Subject: Re: DLL init patch for loading cygwin DLL from MSVC app 28 Oct 1998 18:23:26 -0800 Message-ID: <19981028203649.A19759.cygnus.cygwin32.developers@cygnus.com> References: <9810290044 DOT AA29361 AT modi DOT xraylith DOT wisc DOT edu> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii To: Mumit Khan , cygwin32-developers AT cygnus DOT com On Wed, Oct 28, 1998 at 06:44:25PM -0600, Mumit Khan wrote: > >Here's a tentative, and most certainly not completely correct, patch for >initializing Cygwin guts when a Cygnus DLL is loaded for the first time >from a *non-cygwin* application. > >I can now load cygwin DLLs from MSVC/Mingw apps as well as build working >Java JNI. But of course that doesn't mean that this patch is correct. > >I would very much appreciate it if folks could take a look and see if this >missing anything (or if it's just completely wrong!). This looks like way too much code duplication for me to be comfortable with it. Every time we make a change to something in dcrt0.cc we'd have to remember to change it here, too. I'm also changing some of this for some work in making cygwin thread safe. What was the reason why you couldn't just call dll_crt0, again? cgf >Wed Oct 28 18:39:15 1998 Mumit Khan > > * dll_init.cc (exceptions.h): Include. > (dll_dllcrt0_1): New function. > (dll_dllcrt0): Use. > >--- dll_init.cc.~1 Wed Oct 28 15:28:39 1998 >+++ dll_init.cc Wed Oct 28 18:38:38 1998 >@@ -8,6 +8,7 @@ details. */ > > #include > #include "winsup.h" >+#include "exceptions.h" > #include "dll_init.h" > > extern void check_sanity_and_sync (per_process *); >@@ -395,9 +396,89 @@ LoadedDllNameIterator::~LoadedDllNameIte > // the extern symbols > > extern "C" >+{ >+ /* This is an exported copy of environ which can be used by DLLs >+ which use cygwin.dll. */ >+ extern struct _reent reent_data; >+}; >+ >+/* Initialize Cygwin DLL. This is only done if this is the first cygwin >+ DLL to be loaded and the main app is not Cygwin. */ >+static void >+dll_dllcrt0_1 (per_process *uptr) >+{ >+ /* According to onno AT stack DOT urc DOT tue DOT nl, the exception handler record must >+ be on the stack. */ >+ /* FIXME: Verify forked children get their exception handler set up ok. */ >+ struct exception_list cygwin_except_entry; >+ >+ check_sanity_and_sync (uptr); >+ >+ /* Set the local copy of the pointer into the user space. */ >+ user_data = uptr; >+ >+ /* Nasty static stuff needed by newlib -- point to a local copy of >+ the reent stuff. >+ Note: this MUST be done here (before the forkee code) as the >+ fork copy code doesn't copy the data in libccrt0.cc (that's why we >+ pass in the per_process struct into the .dll from libccrt0). */ >+ >+ *(user_data->impure_ptr_ptr) = &reent_data; >+ _impure_ptr = &reent_data; >+ >+ /* Initialize the cygwin32 subsystem if this is the first process, >+ or attach to the shared data structure if it's already running. */ >+ shared_init (); >+ >+ /* Initialize events. */ >+ events_init (); >+ >+ (void) SetErrorMode (SEM_FAILCRITICALERRORS); >+ >+ /* Initialize the heap. */ >+ heap_init (); >+ >+ /* Initialize SIGSEGV handling, etc... Because the exception handler >+ references data in the shared area, this must be done after >+ shared_init. */ >+ init_exceptions (&cygwin_except_entry); >+ >+ /* Nasty static stuff needed by newlib - initialize it. >+ Note that impure_ptr has already been set up to point to this above >+ NB. This *MUST* be done here, just after the forkee code as some >+ of the calls below (eg. uinfo_init) do stdio calls - this area must >+ be set to zero before then. */ >+ >+ memset (&reent_data, 0, sizeof (reent_data)); >+ reent_data._errno = 0; >+ reent_data._stdin = reent_data.__sf + 0; >+ reent_data._stdout = reent_data.__sf + 1; >+ reent_data._stderr = reent_data.__sf + 2; >+ >+ /* Allocate dtable */ >+ dtable_init (); >+ >+ /* Connect to tty. */ >+ tty_init (); >+ >+ /* Set up standard fds in file descriptor table. */ >+ hinfo_init (); >+ >+ /* Call init of loaded dlls. */ >+ DllList::the().initAll(); >+ >+ set_errno (0); >+} >+ >+extern "C" > int > dll_dllcrt0 (HMODULE h, per_process *p) > { >+ /* initialize Cygwin guts if not already done. */ >+ if (user_data == NULL) >+ { >+ dll_dllcrt0_1 (p); >+ } > return _the.recordDll (h, p); > } > > >Regards, >Mumit -- cgf AT cygnus DOT com http://www.cygnus.com/