This is the mail archive of the cygwin-developers@sourceware.cygnus.com 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]

(patch) winsup noncygwin mess cleanup


Here's a patch to current CVS tree to remove the gross hack that was
there to load Cygwin DLL from a noncygwin app (eg., Java JNI, etc).

What I had ignored previously is that there is a guaranteed way to find
out if Cygwin is being linked in (usual case), or being loaded dynamically 
(noncygwin case) -- just look at the last parameter to the DLL entry
point. Even if you dynamically load a DLL that you've linked to, this
parameter still guarantees the correct result.

This patch will allow the same entry point for all types of apps, and
all the duplicated code in dll_init.cc is now gone. The rest of the
code is now shared, using NON_CYGWIN_APP macro (cf: winsup.h) to
prevent a few things from being initialized in dll_crt0_1. 

One thing will not work for noncygwin apps as currently implemented
-- signal handling -- since it depends on synchronizing with another 
DLL, but that's not going to work due to serialization issues in 
LoadLibrary. I can make it work, but since Chris is going to change 
signal handling anyway ...

Provides backward compatibility, both at source and binary level,
for both cygwin apps and noncygwin extension DLLs.

Please let me know if this is acceptable.

Patch against 1999-12-01 snapshot.

Sat Dec  4 15:25:06 1999  Mumit Khan  <khan@xraylith.wisc.edu>

	* init.cc (dynamically_loaded): New global variable.
	(dll_entry): Use.
	* winsup.h (dynamically_loaded): Declare.
	(NON_CYGWIN_APP): New macro.
	* dcrt0.cc (do_global_ctors): Likewise.
	(set_os_type): Make static again.
	(dll_crt0_1): Handle NON_CYGWIN_APP case.
	* dll_init.cc (dll_dllcrt0_1): Delete.
	(dll_dllcrt0): Handle NON_CYGWIN_APP case. 
	(dll_noncygwin_dllcrt0): Mark obsolescent.
	* libccrt0.cc (cygwin_attach_noncygwin_dll): Delete.
	* pinfo.cc (pinfo_init): Don't inherit parent fds if noncygwin.
	* include/cygwin/cygwin_dll.h (cygwin_attach_noncygwin_dll): Delete
	prototype.
	(_cygwin_noncygwin_dll_entry): Mark obsolescent.

Index: init.cc
===================================================================
RCS file: /home/khan/CVSROOT/cygwin/winsup/init.cc,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 init.cc
--- init.cc	1999/12/04 02:01:43	1.1.1.1
+++ init.cc	1999/12/05 00:02:11
@@ -24,12 +24,15 @@ extern "C" void export_free (void *);
 
 extern void do_global_ctors (void (**in_pfunc)(), int force);
 
+int NO_COPY dynamically_loaded;
+
 int
 WINAPI dll_entry (HANDLE hdll, DWORD reason, void *static_load)
 {
   switch (reason)
     {
     case DLL_PROCESS_ATTACH:
+      dynamically_loaded = (static_load == NULL);
       break;
     case DLL_THREAD_ATTACH:
       break;
Index: winsup.h
===================================================================
RCS file: /home/khan/CVSROOT/cygwin/winsup/winsup.h,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 winsup.h
--- winsup.h	1999/12/04 02:01:45	1.1.1.1
+++ winsup.h	1999/12/04 19:32:05
@@ -30,6 +30,10 @@ details. */
 enum os_type {winNT = 1, win95, win98, win32s, unknown};
 extern os_type os_being_run;
 
+/* Used to check for noncygwin apps. */
+extern int dynamically_loaded;
+#define NON_CYGWIN_APP (dynamically_loaded)
+
 #include <cygwin/version.h>
 
 #define TITLESIZE 1024
Index: dcrt0.cc
===================================================================
RCS file: /home/khan/CVSROOT/cygwin/winsup/dcrt0.cc,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 dcrt0.cc
--- dcrt0.cc	1999/12/04 02:01:42	1.1.1.1
+++ dcrt0.cc	1999/12/05 01:52:42
@@ -72,7 +72,7 @@ do_global_dtors (void)
     }
 }
 
-void
+static void
 do_global_ctors (void (**in_pfunc)(), int force)
 {
   if (!force)
@@ -103,7 +103,7 @@ os_type NO_COPY os_being_run;
    operating system being run.  This information is used internally
    to manage the inconsistency in Win32 API calls between Win32 OSes. */
 /* Cygwin internal */
-void
+static void
 set_os_type ()
 {
   OSVERSIONINFO os_version_info;
@@ -561,7 +561,10 @@ ResourceLocks _reslock NO_COPY;
 MTinterface _mtinterf NO_COPY;
 #endif
 
-/* Take over from libc's crt0.o and start the application.  */
+/* Take over from libc's crt0.o and start the application. Note the
+   various special cases when Cygwin DLL is being runtime loaded (as
+   opposed to being link-time loaded by Cygwin apps) from a non
+   cygwin app via LoadLibrary.  */
 static void
 dll_crt0_1 ()
 {
@@ -689,7 +692,7 @@ dll_crt0_1 ()
 
   /* Set new console title if appropriate. */
 
-  if (display_title)
+  if (display_title && ! NON_CYGWIN_APP)
     {
       char *cp = line;
       if (strip_title_path)
@@ -702,8 +705,13 @@ dll_crt0_1 ()
   /* Allocate dtable */
   dtable_init ();
 
-  /* Initialize signal/subprocess handling. */
-  sigproc_init ();
+  /* Can't use signals in non-cygwin apps since it depends on synchronizing 
+     with a a helper thread.  */
+  if (! NON_CYGWIN_APP)
+    {
+      /* Initialize signal/subprocess handling. */
+      sigproc_init ();
+    }
 
   /* Connect to tty. */
   tty_init ();
@@ -723,9 +731,10 @@ dll_crt0_1 ()
 		  cygwin_version.dll_major, cygwin_version.dll_minor,
 		  cygwin_version.api_major, cygwin_version.api_minor);
 
-  /* Scan the command line and build argv.  Expand wildcards if not called from
-     another cygwin process. */
-  build_argv (line, argv, argc, NOTSTATE (myself, PID_CYGPARENT) && allow_glob);
+  /* Scan the command line and build argv.  Expand wildcards if not 
+     called from another cygwin process. */
+  build_argv (line, argv, argc, 
+	      NOTSTATE (myself, PID_CYGPARENT) && allow_glob);
 
   /* Convert argv[0] to posix rules if it's currently blatantly
      win32 style. */
@@ -746,13 +755,16 @@ dll_crt0_1 ()
   set_errno (0);
   debug_printf ("user_data->main %p", user_data->main);
 
-  /* Flush signals and ensure that signal thread is up and running. */
-  sig_send (NULL, __SIGFLUSH);
+  /* Flush signals and ensure that signal thread is up and running. Can't
+     do this for noncygwin case since the signal thread is blocked due to
+     LoadLibrary serialization. */
+  if (! NON_CYGWIN_APP)
+    sig_send (NULL, __SIGFLUSH);
 
   /* Initialize uid, gid. */
   uinfo_init ();
 
-  if (user_data->main)
+  if (user_data->main && ! NON_CYGWIN_APP)
     exit (user_data->main (argc, argv, *user_data->envptr));
 }
 
Index: dll_init.cc
===================================================================
RCS file: /home/khan/CVSROOT/cygwin/winsup/dll_init.cc,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 dll_init.cc
--- dll_init.cc	1999/12/04 02:01:43	1.1.1.1
+++ dll_init.cc	1999/12/04 21:18:09
@@ -457,244 +457,26 @@ extern "C"
   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. */
-/* FIXME: This function duplicates too much code from dll_crt0_1 in
-   dcrt0.cc.  Need to consolidate this and remove the duplication. */
-
-static NO_COPY STARTUPINFO si;
-static NO_COPY LPBYTE info = NULL;
-# define ciresrv ((struct child_info_fork *)(si.lpReserved2))
-
-extern void alloc_stack (child_info_fork *ci);
-extern void do_global_ctors (void (**)(), int);
-extern void set_os_type ();
-
-static void
-dll_dllcrt0_1 (per_process *uptr)
-{
-  /* According to onno@stack.urc.tue.nl, the exception handler record must
-     be on the stack.  */
-  /* FIXME: Verify forked children get their exception handler set up ok. */
-  exception_list cygwin_except_entry;
-
-  int mypid = 0;
-
-  set_console_handler ();
-  if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),
-		       GetCurrentProcess (), &hMainProc, 0, FALSE,
-			DUPLICATE_SAME_ACCESS))
-    hMainProc = GetCurrentProcess ();
-  else
-    ProtectHandle (hMainProc);
-
-  DuplicateHandle (hMainProc, GetCurrentThread (), hMainProc,
-		   &hMainThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
-  ProtectHandle (hMainThread);
-
-  char zeros[sizeof (ciresrv->zero)] = {0};
-  /* Set the local copy of the pointer into the user space. */
-  user_data = uptr;
-  user_data->heapbase = user_data->heapptr = user_data->heaptop = NULL;
-
-  GetStartupInfo (&si);
-  if (si.cbReserved2 >= EXEC_MAGIC_SIZE &&
-      memcmp (ciresrv->zero, zeros, sizeof (zeros)) == 0)
-    switch (ciresrv->type)
-      {
-	case PROC_EXEC:
-	case PROC_SPAWN:
-	case PROC_FORK:
-	case PROC_FORK1:
-	  {
-	    child_proc_info = ciresrv;
-	    mypid = child_proc_info->cygpid;
-	    cygwin_shared_h = child_proc_info->shared_h;
-	    console_shared_h = child_proc_info->console_h;
-
-	    /* We don't want subprocesses to inherit this */
-	    if (!DuplicateHandle (hMainProc, child_proc_info->parent_alive, hMainProc,
-				  &parent_alive,
-				  0, 0, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
-	      system_printf ("parent_alive DuplicateHandle failed, %E");
-
-	    switch (child_proc_info->type)
-	      {
-		case PROC_EXEC:
-		case PROC_SPAWN:
-		  info = si.lpReserved2 + ciresrv->cb;
-		  break;
-		case PROC_FORK:
-		case PROC_FORK1:
-		  user_data->forkee = child_proc_info->cygpid;
-		  user_data->heaptop = child_proc_info->heaptop;
-		  user_data->heapbase = child_proc_info->heapbase;
-		  user_data->heapptr = child_proc_info->heapptr;
-		  alloc_stack (ciresrv);		// may never return
-	      }
-	    break;
-	  }
-	default:
-	  if ((ciresrv->type & PROC_MAGIC_MASK) == PROC_MAGIC_GENERIC)
-	    api_fatal ("conflicting versions of cygwin1.dll detected.  Use only the most recent version.\n");
-      }
-
-  do_global_ctors (&__CTOR_LIST__, 1);
-
-#ifdef DEBUGGING
-  if (child_proc_info)
-    switch (child_proc_info->type)
-      {
-	case PROC_FORK:
-	case PROC_FORK1:
-	  ProtectHandle (child_proc_info->forker_finished);
-	case PROC_EXEC:
-	  ProtectHandle (child_proc_info->subproc_ready);
-      }
-#endif
-
-  regthread ("main", GetCurrentThreadId ());
-
-  check_sanity_and_sync (user_data);
-
-  /* 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;
-
-#ifdef _MT_SAFE
-  user_data->resourcelocks = &_reslock;
-  user_data->resourcelocks->Init();
-
-  user_data->threadinterface = &_mtinterf;
-  user_data->threadinterface->Init0();
-#endif
-
-  /* Set the os_being_run global. */
-  set_os_type ();
-
-  /* If we didn't call SetFileApisToOEM, console I/O calls would use a
-     different codepage than other Win32 API calls.  In some languages
-     (not English), this would result in "cat > filename" creating a file
-     by a different name than if CreateFile was used to create filename.
-     SetFileApisToOEM prevents this problem by making all calls use the
-     OEM codepage. */
-
-  SetFileApisToOEM ();
-
-  /* Initialize the host dependent constants object. */
-  host_dependent.init ();
-
-  /* Initialize the cygwin subsystem if this is the first process,
-     or attach to the shared data structure if it's already running. */
-  shared_init ();
-
-  if (mypid)
-    set_myself (cygwin_shared->p[mypid]);
-
-  /* Initialize events. */
-  events_init ();
-
-  (void) SetErrorMode (SEM_FAILCRITICALERRORS);
-
-  /* Call this once before heap initializing, to avoid heap fragmentation */
-  extern PSID get_admin_sid (), get_system_sid (), get_world_sid ();
-  get_admin_sid ();
-  get_system_sid ();
-  get_world_sid ();
-
-  /* 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);
-
-  if (user_data->forkee)
-    {
-      /* If we've played with the stack, stacksize != 0.  That means that
-	 fork() was invoked from other than the main thread.  Make sure that
-	 frame pointer is referencing the new stack so that the OS knows what
-	 to do when it needs to increase the size of the stack.
-
-	 NOTE: Don't do anything that involves the stack until you've completed
-	 this step. */
-      if (ciresrv->stacksize)
-	{
-	  asm ("movl %0,%%fs:4" : : "r" (ciresrv->stackbottom));
-	  asm ("movl %0,%%fs:8" : : "r" (ciresrv->stacktop));
-	}
-
-      longjmp (ciresrv->jmp, ciresrv->cygpid);
-    }
-
-  pinfo_init (NULL);		/* Initialize our process table 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. */
-
-#ifdef _MT_SAFE
-  user_data->threadinterface->ClearReent();
-  user_data->threadinterface->Init1();
-#else
-  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;
-#endif
-
-  /* Allocate dtable */
-  dtable_init ();
-
-  /* NOTE: No call to sigproc_init() nor to tty_init(). These create
-     threads and uses synchronization, and that's a NO-NO from a
-     DLL entry point thanks to the Windows serialization when loading
-     DLLs dynamically. See MSDN docs for more info.  */
-
-  /* Set up standard fds in file descriptor table. */
-  hinfo_init ();
-
-  /* Initialize uid, gid. */
-  uinfo_init ();
-
-  syscall_printf ("Application CYGWIN version: %d.%d, api: %d.%d",
-		  user_data->dll_major, user_data->dll_minor,
-		  user_data->api_major, user_data->api_minor);
-  syscall_printf ("CYGWIN DLL version: %d.%d, api: %d.%d",
-		  cygwin_version.dll_major, cygwin_version.dll_minor,
-		  cygwin_version.api_major, cygwin_version.api_minor);
-
-  /* Call init of loaded dlls. */
-  DllList::the().initAll();
-
-  set_errno (0);
-}
-
 extern "C"
 int
 dll_dllcrt0 (HMODULE h, per_process *p)
 {
+  /* Partially initialize Cygwin guts for non-cygwin apps. */
+  if (NON_CYGWIN_APP && (! user_data || user_data->magic_biscuit == 0))
+    {
+      dll_crt0 (p);
+    }
   return _the.recordDll (h, p);
 }
 
+/* OBSOLETE: This function is obsolescent and will go away in the
+   future.  Cygwin can now handle being loaded from a noncygwin app
+   using the same entry point. */
+
 extern "C"
 int
 dll_noncygwin_dllcrt0 (HMODULE h, per_process *p)
 {
-  /* Partially initialize Cygwin guts for non-cygwin apps. */
-  if (! user_data || user_data->magic_biscuit == 0)
-    {
-      dll_dllcrt0_1 (p);
-    }
   return dll_dllcrt0 (h, p);
 }
 
Index: libccrt0.cc
===================================================================
RCS file: /home/khan/CVSROOT/cygwin/winsup/libccrt0.cc,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 libccrt0.cc
--- libccrt0.cc	1999/12/04 02:01:43	1.1.1.1
+++ libccrt0.cc	1999/12/04 21:47:55
@@ -94,13 +94,3 @@ cygwin_attach_dll (HMODULE h, MainFunc f
   return dll_dllcrt0 (h, &this_proc);
 }
 
-/* for a loaded dll from a non-cygwin app */
-int
-cygwin_attach_noncygwin_dll (HMODULE h, MainFunc f)
-{
-  cygwin_crt0_common (f);
-
-  /* jump into the dll. */
-  return dll_noncygwin_dllcrt0 (h, &this_proc);
-}
-
Index: pinfo.cc
===================================================================
RCS file: /home/khan/CVSROOT/cygwin/winsup/pinfo.cc,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 pinfo.cc
--- pinfo.cc	1999/12/04 02:01:43	1.1.1.1
+++ pinfo.cc	1999/12/05 00:44:54
@@ -64,12 +64,16 @@ pinfo_init (LPBYTE info)
 
       myself->process_state |= PID_CYGPARENT;
 
-      /* Inherit file descriptor information from parent in info.
-       */
-      LPBYTE b = dtable.de_linearize_fd_array (info);
-      extern char title_buf[];
-      if (b && *b)
-	old_title = strcpy (title_buf, (char *)b);
+      /* Inherit file descriptor information from parent in info. 
+         FIXME: It fails for a non cygwin app that is exec'd from a cygwin 
+	 app (eg., the shell), so turn it off for now. Sigh. */
+      if (! NON_CYGWIN_APP)
+        {
+	  LPBYTE b = dtable.de_linearize_fd_array (info);
+	  extern char title_buf[];
+	  if (b && *b)
+	    old_title = strcpy (title_buf, (char *)b);
+	}
     }
   else
     {
Index: include/cygwin/cygwin_dll.h
===================================================================
RCS file: /home/khan/CVSROOT/cygwin/winsup/include/cygwin/cygwin_dll.h,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 cygwin_dll.h
--- cygwin_dll.h	1999/12/04 02:01:49	1.1.1.1
+++ cygwin_dll.h	1999/12/04 21:47:48
@@ -29,7 +29,6 @@ CDECL_BEGIN								      \
 									      \
   int WINAPI Entry (HANDLE h, DWORD reason, void *ptr);		              \
   extern int cygwin_attach_dll ();					      \
-  extern int cygwin_attach_noncygwin_dll ();				      \
   extern void cygwin_detach_dll ();	                      		      \
 CDECL_END								      \
 									      \
@@ -88,31 +87,10 @@ int WINAPI _cygwin_dll_entry (HANDLE h, 
   return ret;								      \
 }									      \
 									      \
+/* OBSOLETE: This is only provided for source level compatibility. */         \
 int WINAPI _cygwin_noncygwin_dll_entry (HANDLE h, DWORD reason, void *ptr)    \
 {									      \
-  int ret;								      \
-  ret = 1;								      \
-									      \
-  switch (reason)							      \
-  {									      \
-    case DLL_PROCESS_ATTACH:						      \
-    {									      \
-      storedHandle = h;							      \
-      storedReason = reason;						      \
-      storedPtr = ptr;							      \
-      dll_index = cygwin_attach_noncygwin_dll (h, &__dllMain);   	      \
-      if (dll_index == -1)						      \
-	ret = 0;							      \
-    }									      \
-    break;								      \
-									      \
-    default:						      		      \
-    {									      \
-      ret = _cygwin_dll_entry (h, reason, ptr);				      \
-    }									      \
-    break;								      \
-  }									      \
-  return ret;								      \
+  return _cygwin_dll_entry (h, reason, ptr);				      \
 }									      \
 
 #endif /* __CYGWIN_CYGWIN_DLL_H__ */

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