delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin-developers/1998/10/28/17:26:32

From: khan AT xraylith DOT wisc DOT edu (Mumit Khan)
Subject: DLL init patch for loading cygwin DLL from MSVC app
28 Oct 1998 17:26:32 -0800 :
Message-ID: <9810290044.AA29361.cygnus.cygwin32.developers@modi.xraylith.wisc.edu>
To: cygwin32-developers AT cygnus DOT com

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 -


  webmaster     delorie software   privacy  
  Copyright 2019   by DJ Delorie     Updated Jul 2019