Mail Archives: cygwin-developers/1998/10/28/17:26:32
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!).
Wed Oct 28 18:39:15 1998 Mumit Khan <khan AT xraylith DOT wisc DOT edu>
* 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 <stdlib.h>
#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
- Raw text -