OSDN Git Service

* globals.cc (enum exit_states::ES_GLOBAL_DTORS): Delete.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / dcrt0.cc
index 9ffbd72..9cff06f 100644 (file)
@@ -16,6 +16,7 @@ details. */
 #include <stdlib.h>
 #include "glob.h"
 #include <ctype.h>
+#include <locale.h>
 #include "environ.h"
 #include "sigproc.h"
 #include "pinfo.h"
@@ -47,6 +48,8 @@ static char NO_COPY **envp;
 
 static char title_buf[TITLESIZE + 1];
 
+bool NO_COPY jit_debug;
+
 static void
 do_global_dtors ()
 {
@@ -228,7 +231,15 @@ globify (char *word, char **&argv, int &argc, int &argvlen)
            else if (s[1] == quote || s[1] == '\\')
              s++;
            *p++ = '\\';
-           *p++ = *s;
+           size_t cnt = isascii (*s) ? 1 : mbtowc (NULL, s, MB_CUR_MAX);
+           if (cnt <= 1 || cnt == (size_t)-1)
+             *p++ = *s;
+           else
+             {
+               --s;
+               while (cnt-- > 0)
+                 *p++ = *++s;
+             }
          }
        if (*s == quote)
          p--;
@@ -490,6 +501,7 @@ initial_env ()
       if (strstr (buf1, buf))
        {
          error_start_init (p);
+         jit_debug = true;
          try_to_debug ();
          console_printf ("*** Sending Break.  gdb may issue spurious SIGTRAP message.\n");
          break_here ();
@@ -562,7 +574,7 @@ void
 child_info_fork::handle_fork ()
 {
   cygheap_fixup_in_child (false);
-  memory_init ();
+  memory_init (false);
   myself.thisproc (NULL);
   myself->uid = cygheap->user.real_uid;
   myself->gid = cygheap->user.real_gid;
@@ -589,7 +601,7 @@ child_info_spawn::handle_spawn ()
   extern void fixup_lockf_after_exec ();
   HANDLE h;
   cygheap_fixup_in_child (true);
-  memory_init ();
+  memory_init (false);
   if (!moreinfo->myself_pinfo ||
       !DuplicateHandle (hMainProc, moreinfo->myself_pinfo, hMainProc, &h, 0,
                        FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
@@ -623,6 +635,10 @@ child_info_spawn::handle_spawn ()
   fixup_lockf_after_exec ();
 }
 
+#if 0
+/* Setting the TS-aware flag in the application's PE header is sufficient.
+   Just keep this in as a reminder. */
+
 static DEP_SYSTEM_POLICY_TYPE dep_system_policy = (DEP_SYSTEM_POLICY_TYPE) -1;
 
 static void
@@ -647,6 +663,7 @@ disable_dep ()
   if (ppolicy > 0 && !perm && !SetProcessDEPPolicy (0))
     debug_printf ("SetProcessDEPPolicy: %E");
 }
+#endif
 
 void __stdcall
 dll_crt0_0 ()
@@ -688,7 +705,7 @@ dll_crt0_0 ()
 
   child_proc_info = get_cygwin_startup_info ();
   if (!child_proc_info)
-    memory_init ();
+    memory_init (true);
   else
     {
       cygwin_user_h = child_proc_info->user_h;
@@ -712,10 +729,11 @@ dll_crt0_0 ()
   events_init ();
   tty_list::init_session ();
 
-  /* FIXME: This is hopefully a temporary hack, at least until the support
-     case at Microsoft has been closed one way or the other.
+#if 0
+  /* Setting the TS-aware flag in the application's PE header is sufficient.
+     Just keep this in as a reminder. */
 
-     The disable_dep function disables DEP for all Cygwin processes if
+  /* The disable_dep function disables DEP for all Cygwin processes if
      the process runs on a Windows Server 2008 with Terminal Services
      installed.  This combination (TS+DEP) breaks *some* Cygwin
      applications.  The Terminal Service specific DLL tsappcmp.dll
@@ -732,6 +750,7 @@ dll_crt0_0 ()
      Idle idea: Adding EXECUTE protection to all text segment pages? */
   if (wincap.ts_has_dep_problem ())
     disable_dep ();
+#endif
 
   debug_printf ("finished dll_crt0_0 initialization");
 }
@@ -914,6 +933,8 @@ dll_crt0_1 (void *)
      do this for noncygwin case since the signal thread is blocked due to
      LoadLibrary serialization. */
   ld_preload ();
+  /* Reset current application locale to "C" per POSIX */
+  _setlocale_r (_REENT, LC_CTYPE, "C");
   if (user_data->main)
     cygwin_exit (user_data->main (__argc, __argv, *user_data->envptr));
   __asm__ ("                           \n\
@@ -972,8 +993,17 @@ cygwin_dll_init ()
 extern "C" void
 __main (void)
 {
+  /* Ordering is critical here.  DLL ctors have already been
+     run as they were being loaded, so we should stack the 
+     queued call to DLL dtors now.  */
+  atexit (dll_global_dtors);
   do_global_ctors (user_data->ctors, false);
+  /* Now we have run global ctors, register their dtors.  */
   atexit (do_global_dtors);
+  /* At exit, global dtors will run first, so the app can still
+     use shared library functions while terminating; then the
+     DLLs will be destroyed; finally newlib will shut down stdio
+     and terminate itself.  */
 }
 
 void __stdcall
@@ -992,12 +1022,6 @@ do_exit (int status)
 
   lock_process until_exit (true);
 
-  if (exit_state < ES_GLOBAL_DTORS)
-    {
-      exit_state = ES_GLOBAL_DTORS;
-      dll_global_dtors ();
-    }
-
   if (exit_state < ES_EVENTS_TERMINATE)
     {
       exit_state = ES_EVENTS_TERMINATE;