OSDN Git Service

Rename cygWFMO to cygwait throughout and use the magic of polymorphism to "wait
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / dcrt0.cc
1 /* dcrt0.cc -- essentially the main() for the Cygwin dll
2
3    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4    2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
5
6 This file is part of Cygwin.
7
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
10 details. */
11
12 #include "winsup.h"
13 #include "miscfuncs.h"
14 #include <unistd.h>
15 #include <stdlib.h>
16 #include "glob.h"
17 #include <ctype.h>
18 #include <locale.h>
19 #include "environ.h"
20 #include "sigproc.h"
21 #include "pinfo.h"
22 #include "cygerrno.h"
23 #define NEED_VFORK
24 #include "perprocess.h"
25 #include "path.h"
26 #include "fhandler.h"
27 #include "dtable.h"
28 #include "cygheap.h"
29 #include "child_info_magic.h"
30 #include "cygtls.h"
31 #include "shared_info.h"
32 #include "cygwin_version.h"
33 #include "dll_init.h"
34 #include "heap.h"
35 #include "tls_pbuf.h"
36 #include "exception.h"
37 #include "cygxdr.h"
38 #include "fenv.h"
39 #include "ntdll.h"
40
41 #define MAX_AT_FILE_LEVEL 10
42
43 #define PREMAIN_LEN (sizeof (user_data->premain) / sizeof (user_data->premain[0]))
44
45 extern "C" void cygwin_exit (int) __attribute__ ((noreturn));
46 extern "C" void __sinit (_reent *);
47
48 static int NO_COPY envc;
49 static char NO_COPY **envp;
50
51 bool NO_COPY jit_debug;
52
53 static void
54 do_global_dtors ()
55 {
56   void (**pfunc) () = user_data->dtors;
57   if (pfunc)
58     {
59       user_data->dtors = NULL;
60       while (*++pfunc)
61         (*pfunc) ();
62     }
63 }
64
65 static void __stdcall
66 do_global_ctors (void (**in_pfunc)(), int force)
67 {
68   if (!force && in_forkee)
69     return;             // inherit constructed stuff from parent pid
70
71   /* Run ctors backwards, so skip the first entry and find how many
72      there are, then run them. */
73
74   void (**pfunc) () = in_pfunc;
75
76   while (*++pfunc)
77     ;
78   while (--pfunc > in_pfunc)
79     (*pfunc) ();
80 }
81
82 /*
83  * Replaces @file in the command line with the contents of the file.
84  * There may be multiple @file's in a single command line
85  * A \@file is replaced with @file so that echo \@foo would print
86  * @foo and not the contents of foo.
87  */
88 static bool __stdcall
89 insert_file (char *name, char *&cmd)
90 {
91   HANDLE f;
92   DWORD size;
93   tmp_pathbuf tp;
94
95   PWCHAR wname = tp.w_get ();
96   sys_mbstowcs (wname, NT_MAX_PATH, name + 1);
97   f = CreateFileW (wname,
98                    GENERIC_READ,                /* open for reading     */
99                    FILE_SHARE_VALID_FLAGS,      /* share for reading    */
100                    &sec_none_nih,               /* default security     */
101                    OPEN_EXISTING,               /* existing file only   */
102                    FILE_ATTRIBUTE_NORMAL,       /* normal file          */
103                    NULL);                       /* no attr. template    */
104
105   if (f == INVALID_HANDLE_VALUE)
106     {
107       debug_printf ("couldn't open file '%s', %E", name);
108       return false;
109     }
110
111   /* This only supports files up to about 4 billion bytes in
112      size.  I am making the bold assumption that this is big
113      enough for this feature */
114   size = GetFileSize (f, NULL);
115   if (size == 0xFFFFFFFF)
116     {
117       debug_printf ("couldn't get file size for '%s', %E", name);
118       return false;
119     }
120
121   int new_size = strlen (cmd) + size + 2;
122   char *tmp = (char *) malloc (new_size);
123   if (!tmp)
124     {
125       debug_printf ("malloc failed, %E");
126       return false;
127     }
128
129   /* realloc passed as it should */
130   DWORD rf_read;
131   BOOL rf_result;
132   rf_result = ReadFile (f, tmp, size, &rf_read, NULL);
133   CloseHandle (f);
134   if (!rf_result || (rf_read != size))
135     {
136       debug_printf ("ReadFile failed, %E");
137       return false;
138     }
139
140   tmp[size++] = ' ';
141   strcpy (tmp + size, cmd);
142   cmd = tmp;
143   return true;
144 }
145
146 static inline int
147 isquote (char c)
148 {
149   char ch = c;
150   return ch == '"' || ch == '\'';
151 }
152
153 /* Step over a run of characters delimited by quotes */
154 static /*__inline*/ char *
155 quoted (char *cmd, int winshell)
156 {
157   char *p;
158   char quote = *cmd;
159
160   if (!winshell)
161     {
162       char *p;
163       strcpy (cmd, cmd + 1);
164       if (*(p = strechr (cmd, quote)))
165         strcpy (p, p + 1);
166       return p;
167     }
168
169   const char *s = quote == '\'' ? "'" : "\\\"";
170   /* This must have been run from a Windows shell, so preserve
171      quotes for globify to play with later. */
172   while (*cmd && *++cmd)
173     if ((p = strpbrk (cmd, s)) == NULL)
174       {
175         cmd = strchr (cmd, '\0');       // no closing quote
176         break;
177       }
178     else if (*p == '\\')
179       cmd = ++p;
180     else if (quote == '"' && p[1] == '"')
181       {
182         *p = '\\';
183         cmd = ++p;                      // a quoted quote
184       }
185     else
186       {
187         cmd = p + 1;            // point to after end
188         break;
189       }
190   return cmd;
191 }
192
193 /* Perform a glob on word if it contains wildcard characters.
194    Also quote every character between quotes to force glob to
195    treat the characters literally. */
196 static int __stdcall
197 globify (char *word, char **&argv, int &argc, int &argvlen)
198 {
199   if (*word != '~' && strpbrk (word, "?*[\"\'(){}") == NULL)
200     return 0;
201
202   int n = 0;
203   char *p, *s;
204   int dos_spec = isdrive (word);
205   if (!dos_spec && isquote (*word) && word[1] && word[2])
206     dos_spec = isdrive (word + 1);
207
208   /* We'll need more space if there are quoting characters in
209      word.  If that is the case, doubling the size of the
210      string should provide more than enough space. */
211   if (strpbrk (word, "'\""))
212     n = strlen (word);
213   char pattern[strlen (word) + ((dos_spec + 1) * n) + 1];
214
215   /* Fill pattern with characters from word, quoting any
216      characters found within quotes. */
217   for (p = pattern, s = word; *s != '\000'; s++, p++)
218     if (!isquote (*s))
219       {
220         if (dos_spec && *s == '\\')
221           *p++ = '\\';
222         *p = *s;
223       }
224     else
225       {
226         char quote = *s;
227         while (*++s && *s != quote)
228           {
229             if (dos_spec || *s != '\\')
230               /* nothing */;
231             else if (s[1] == quote || s[1] == '\\')
232               s++;
233             *p++ = '\\';
234             size_t cnt = isascii (*s) ? 1 : mbtowc (NULL, s, MB_CUR_MAX);
235             if (cnt <= 1 || cnt == (size_t)-1)
236               *p++ = *s;
237             else
238               {
239                 --s;
240                 while (cnt-- > 0)
241                   *p++ = *++s;
242               }
243           }
244         if (*s == quote)
245           p--;
246         if (*s == '\0')
247             break;
248       }
249
250   *p = '\0';
251
252   glob_t gl;
253   gl.gl_offs = 0;
254
255   /* Attempt to match the argument.  Return just word (minus quoting) if no match. */
256   if (glob (pattern, GLOB_TILDE | GLOB_NOCHECK | GLOB_BRACE | GLOB_QUOTE, NULL, &gl) || !gl.gl_pathc)
257     return 0;
258
259   /* Allocate enough space in argv for the matched filenames. */
260   n = argc;
261   if ((argc += gl.gl_pathc) > argvlen)
262     {
263       argvlen = argc + 10;
264       argv = (char **) realloc (argv, (1 + argvlen) * sizeof (argv[0]));
265     }
266
267   /* Copy the matched filenames to argv. */
268   char **gv = gl.gl_pathv;
269   char **av = argv + n;
270   while (*gv)
271     {
272       debug_printf ("argv[%d] = '%s'", n++, *gv);
273       *av++ = *gv++;
274     }
275
276   /* Clean up after glob. */
277   free (gl.gl_pathv);
278   return 1;
279 }
280
281 /* Build argv, argc from string passed from Windows.  */
282
283 static void __stdcall
284 build_argv (char *cmd, char **&argv, int &argc, int winshell)
285 {
286   int argvlen = 0;
287   int nesting = 0;              // monitor "nesting" from insert_file
288
289   argc = 0;
290   argvlen = 0;
291   argv = NULL;
292
293   /* Scan command line until there is nothing left. */
294   while (*cmd)
295     {
296       /* Ignore spaces */
297       if (issep (*cmd))
298         {
299           cmd++;
300           continue;
301         }
302
303       /* Found the beginning of an argument. */
304       char *word = cmd;
305       char *sawquote = NULL;
306       while (*cmd)
307         {
308           if (*cmd != '"' && (!winshell || *cmd != '\''))
309             cmd++;              // Skip over this character
310           else
311             /* Skip over characters until the closing quote */
312             {
313               sawquote = cmd;
314               cmd = quoted (cmd, winshell && argc > 0);
315             }
316           if (issep (*cmd))     // End of argument if space
317             break;
318         }
319       if (*cmd)
320         *cmd++ = '\0';          // Terminate `word'
321
322       /* Possibly look for @file construction assuming that this isn't
323          the very first argument and the @ wasn't quoted */
324       if (argc && sawquote != word && *word == '@')
325         {
326           if (++nesting > MAX_AT_FILE_LEVEL)
327             api_fatal ("Too many levels of nesting for %s", word);
328           if (insert_file (word, cmd))
329               continue;                 // There's new stuff in cmd now
330         }
331
332       /* See if we need to allocate more space for argv */
333       if (argc >= argvlen)
334         {
335           argvlen = argc + 10;
336           argv = (char **) realloc (argv, (1 + argvlen) * sizeof (argv[0]));
337         }
338
339       /* Add word to argv file after (optional) wildcard expansion. */
340       if (!winshell || !argc || !globify (word, argv, argc, argvlen))
341         {
342           debug_printf ("argv[%d] = '%s'", argc, word);
343           argv[argc++] = word;
344         }
345     }
346
347   argv[argc] = NULL;
348
349   debug_printf ("argc %d", argc);
350 }
351
352 /* sanity and sync check */
353 void __stdcall
354 check_sanity_and_sync (per_process *p)
355 {
356   /* Sanity check to make sure developers didn't change the per_process    */
357   /* struct without updating SIZEOF_PER_PROCESS [it makes them think twice */
358   /* about changing it].                                                   */
359   if (sizeof (per_process) != SIZEOF_PER_PROCESS)
360     api_fatal ("per_process sanity check failed");
361
362   /* Make sure that the app and the dll are in sync. */
363
364   /* Complain if older than last incompatible change */
365   if (p->dll_major < CYGWIN_VERSION_DLL_EPOCH)
366     api_fatal ("cygwin DLL and APP are out of sync -- DLL version mismatch %d < %d",
367                p->dll_major, CYGWIN_VERSION_DLL_EPOCH);
368
369   /* magic_biscuit != 0 if using the old style version numbering scheme.  */
370   if (p->magic_biscuit != SIZEOF_PER_PROCESS)
371     api_fatal ("Incompatible cygwin .dll -- incompatible per_process info %d != %d",
372                p->magic_biscuit, SIZEOF_PER_PROCESS);
373
374   /* Complain if incompatible API changes made */
375   if (p->api_major > cygwin_version.api_major)
376     api_fatal ("cygwin DLL and APP are out of sync -- API version mismatch %d > %d",
377                p->api_major, cygwin_version.api_major);
378
379   /* This is a kludge to work around a version of _cygwin_common_crt0
380      which overwrote the cxx_malloc field with the local DLL copy.
381      Hilarity ensues if the DLL is not loaded while the process
382      is forking. */
383   __cygwin_user_data.cxx_malloc = &default_cygwin_cxx_malloc;
384 }
385
386 child_info NO_COPY *child_proc_info = NULL;
387
388 #define CYGWIN_GUARD (PAGE_EXECUTE_READWRITE | PAGE_GUARD)
389
390 void
391 child_info_fork::alloc_stack_hard_way (volatile char *b)
392 {
393   void *stack_ptr;
394   DWORD stacksize;
395
396   /* First check if the requested stack area is part of the user heap
397      or part of a mmapped region.  If so, we have been started from a
398      pthread with an application-provided stack, and the stack has just
399      to be used as is. */
400   if ((stacktop >= cygheap->user_heap.base
401       && stackbottom <= cygheap->user_heap.max)
402       || is_mmapped_region ((caddr_t) stacktop, (caddr_t) stackbottom))
403     return;
404
405   /* First, try to reserve the entire stack. */
406   stacksize = (char *) stackbottom - (char *) stackaddr;
407   if (!VirtualAlloc (stackaddr, stacksize, MEM_RESERVE, PAGE_NOACCESS))
408     api_fatal ("fork: can't reserve memory for stack %p - %p, %E",
409                stackaddr, stackbottom);
410   stacksize = (char *) stackbottom - (char *) stacktop;
411   stack_ptr = VirtualAlloc (stacktop, stacksize, MEM_COMMIT,
412                             PAGE_EXECUTE_READWRITE);
413   if (!stack_ptr)
414     abort ("can't commit memory for stack %p(%d), %E", stacktop, stacksize);
415   if (guardsize != (size_t) -1)
416     {
417       /* Allocate PAGE_GUARD page if it still fits. */
418       if (stack_ptr > stackaddr)
419         {
420           stack_ptr = (void *) ((LPBYTE) stack_ptr
421                                         - wincap.page_size ());
422           if (!VirtualAlloc (stack_ptr, wincap.page_size (), MEM_COMMIT,
423                              CYGWIN_GUARD))
424             api_fatal ("fork: couldn't allocate new stack guard page %p, %E",
425                        stack_ptr);
426         }
427       /* Allocate POSIX guard pages. */
428       if (guardsize > 0)
429         VirtualAlloc (stackaddr, guardsize, MEM_COMMIT, PAGE_NOACCESS);
430     }
431   b[0] = '\0';
432 }
433
434 void *getstack (void *) __attribute__ ((noinline));
435 volatile char *
436 getstack (volatile char * volatile p)
437 {
438   *p ^= 1;
439   *p ^= 1;
440   return p - 4096;
441 }
442
443 /* extend the stack prior to fork longjmp */
444
445 void
446 child_info_fork::alloc_stack ()
447 {
448   volatile char * volatile esp;
449   __asm__ volatile ("movl %%esp,%0": "=r" (esp));
450   if (_tlsbase != stackbottom)
451     alloc_stack_hard_way (esp);
452   else
453     {
454       char *st = (char *) stacktop - 4096;
455       while (_tlstop >= st)
456         esp = getstack (esp);
457       stackaddr = 0;
458     }
459 }
460
461 extern "C" void
462 break_here ()
463 {
464   static int NO_COPY sent_break;
465   if (!sent_break++)
466     DebugBreak ();
467   debug_printf ("break here");
468 }
469
470 static void
471 initial_env ()
472 {
473   if (GetEnvironmentVariableA ("CYGWIN_TESTING", NULL, 0))
474     _cygwin_testing = 1;
475
476 #ifdef DEBUGGING
477   DWORD len;
478   char buf[NT_MAX_PATH];
479   if (GetEnvironmentVariableA ("CYGWIN_DEBUG", buf, sizeof (buf) - 1))
480     {
481       char buf1[NT_MAX_PATH];
482       len = GetModuleFileName (NULL, buf1, NT_MAX_PATH);
483       strlwr (buf1);
484       strlwr (buf);
485       char *p = strpbrk (buf, ":=");
486       if (!p)
487         p = (char *) "gdb.exe -nw";
488       else
489         *p++ = '\0';
490       if (strstr (buf1, buf))
491         {
492           error_start_init (p);
493           jit_debug = true;
494           try_to_debug ();
495           console_printf ("*** Sending Break.  gdb may issue spurious SIGTRAP message.\n");
496           break_here ();
497         }
498     }
499 #endif
500 }
501
502 child_info *
503 get_cygwin_startup_info ()
504 {
505   STARTUPINFO si;
506
507   GetStartupInfo (&si);
508   child_info *res = (child_info *) si.lpReserved2;
509
510   if (si.cbReserved2 < EXEC_MAGIC_SIZE || !res
511       || res->intro != PROC_MAGIC_GENERIC || res->magic != CHILD_INFO_MAGIC)
512     {
513       strace.activate (false);
514       res = NULL;
515     }
516   else
517     {
518       if ((res->intro & OPROC_MAGIC_MASK) == OPROC_MAGIC_GENERIC)
519         multiple_cygwin_problem ("proc intro", res->intro, 0);
520       else if (res->cygheap != (void *) &_cygheap_start)
521         multiple_cygwin_problem ("cygheap base", (DWORD) res->cygheap,
522                                  (DWORD) &_cygheap_start);
523
524       unsigned should_be_cb = 0;
525       switch (res->type)
526         {
527           case _CH_FORK:
528             in_forkee = true;
529             should_be_cb = sizeof (child_info_fork);
530             /* fall through */;
531           case _CH_SPAWN:
532           case _CH_EXEC:
533             if (!should_be_cb)
534               should_be_cb = sizeof (child_info_spawn);
535             if (should_be_cb != res->cb)
536               multiple_cygwin_problem ("proc size", res->cb, should_be_cb);
537             else if (sizeof (fhandler_union) != res->fhandler_union_cb)
538               multiple_cygwin_problem ("fhandler size", res->fhandler_union_cb, sizeof (fhandler_union));
539             if (res->isstraced ())
540               {
541                 while (!being_debugged ())
542                   yield ();
543                 strace.activate (res->type == _CH_FORK);
544               }
545             break;
546           default:
547             system_printf ("unknown exec type %d", res->type);
548             /* intentionally fall through */
549           case _CH_WHOOPS:
550             res = NULL;
551             break;
552         }
553     }
554
555   return res;
556 }
557
558 #define dll_data_start &_data_start__
559 #define dll_data_end &_data_end__
560 #define dll_bss_start &_bss_start__
561 #define dll_bss_end &_bss_end__
562
563 void
564 child_info_fork::handle_fork ()
565 {
566   cygheap_fixup_in_child (false);
567   memory_init (false);
568   myself.thisproc (NULL);
569   myself->uid = cygheap->user.real_uid;
570   myself->gid = cygheap->user.real_gid;
571
572   child_copy (parent, false,
573               "dll data", dll_data_start, dll_data_end,
574               "dll bss", dll_bss_start, dll_bss_end,
575               "user heap", cygheap->user_heap.base, cygheap->user_heap.ptr,
576               NULL);
577
578   /* Do the relocations here.  These will actually likely be overwritten by the
579      below child_copy but we do them here in case there is a read-only section
580      which does not get copied by fork. */
581   _pei386_runtime_relocator (user_data);
582
583   /* step 2 now that the dll has its heap filled in, we can fill in the
584      user's data and bss since user_data is now filled out. */
585   child_copy (parent, false,
586               "data", user_data->data_start, user_data->data_end,
587               "bss", user_data->bss_start, user_data->bss_end,
588               NULL);
589
590   if (fixup_mmaps_after_fork (parent))
591     api_fatal ("recreate_mmaps_after_fork_failed");
592 }
593
594 void
595 child_info_spawn::handle_spawn ()
596 {
597   extern void fixup_lockf_after_exec ();
598   HANDLE h;
599   cygheap_fixup_in_child (true);
600   memory_init (false);
601   if (!moreinfo->myself_pinfo ||
602       !DuplicateHandle (GetCurrentProcess (), moreinfo->myself_pinfo,
603                         GetCurrentProcess (), &h, 0,
604                         FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
605     h = NULL;
606   myself.thisproc (h);
607   __argc = moreinfo->argc;
608   __argv = moreinfo->argv;
609   envp = moreinfo->envp;
610   envc = moreinfo->envc;
611   if (!dynamically_loaded)
612     cygheap->fdtab.fixup_after_exec ();
613   if (__stdin >= 0)
614     cygheap->fdtab.move_fd (__stdin, 0);
615   if (__stdout >= 0)
616     cygheap->fdtab.move_fd (__stdout, 1);
617   cygheap->user.groups.clear_supp ();
618
619   /* If we're execing we may have "inherited" a list of children forked by the
620      previous process executing under this pid.  Reattach them here so that we
621      can wait for them.  */
622   if (type == _CH_EXEC)
623     reattach_children ();
624
625   ready (true);
626
627   /* Need to do this after debug_fixup_after_fork_exec or DEBUGGING handling of
628      handles might get confused. */
629   CloseHandle (child_proc_info->parent);
630   child_proc_info->parent = NULL;
631
632   signal_fixup_after_exec ();
633   fixup_lockf_after_exec ();
634 }
635
636 /* Retrieve and store system directory for later use.  Note that the
637    directory is stored with a trailing backslash! */
638 static void
639 init_windows_system_directory ()
640 {
641   windows_system_directory_length =
642         GetSystemDirectoryW (windows_system_directory, MAX_PATH);
643   if (windows_system_directory_length == 0)
644     api_fatal ("can't find windows system directory");
645   windows_system_directory[windows_system_directory_length++] = L'\\';
646   windows_system_directory[windows_system_directory_length] = L'\0';
647 }
648
649 void
650 dll_crt0_0 ()
651 {
652   child_proc_info = get_cygwin_startup_info ();
653   init_windows_system_directory ();
654   init_global_security ();
655   initial_env ();
656
657   SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
658
659   lock_process::init ();
660   _impure_ptr = _GLOBAL_REENT;
661   _impure_ptr->_stdin = &_impure_ptr->__sf[0];
662   _impure_ptr->_stdout = &_impure_ptr->__sf[1];
663   _impure_ptr->_stderr = &_impure_ptr->__sf[2];
664   _impure_ptr->_current_locale = "C";
665   user_data->impure_ptr = _impure_ptr;
666   user_data->impure_ptr_ptr = &_impure_ptr;
667
668   DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
669                    GetCurrentProcess (), &hMainThread,
670                    0, false, DUPLICATE_SAME_ACCESS);
671
672   NtOpenProcessToken (NtCurrentProcess (), MAXIMUM_ALLOWED, &hProcToken);
673   set_cygwin_privileges (hProcToken);
674
675   device::init ();
676   do_global_ctors (&__CTOR_LIST__, 1);
677   cygthread::init ();
678
679   if (!child_proc_info)
680     memory_init (true);
681   else
682     {
683       cygwin_user_h = child_proc_info->user_h;
684       switch (child_proc_info->type)
685         {
686           case _CH_FORK:
687             fork_info->handle_fork ();
688             break;
689           case _CH_SPAWN:
690           case _CH_EXEC:
691             spawn_info->handle_spawn ();
692             break;
693         }
694     }
695
696   user_data->threadinterface->Init ();
697
698   _cygtls::init ();
699
700   /* Initialize events */
701   events_init ();
702   tty_list::init_session ();
703
704   _main_tls = &_my_tls;
705
706   /* Initialize signal processing here, early, in the hopes that the creation
707      of a thread early in the process will cause more predictability in memory
708      layout for the main thread. */
709   if (!dynamically_loaded)
710     sigproc_init ();
711
712   debug_printf ("finished dll_crt0_0 initialization");
713 }
714
715 /* Take over from libc's crt0.o and start the application. Note the
716    various special cases when Cygwin DLL is being runtime loaded (as
717    opposed to being link-time loaded by Cygwin apps) from a non
718    cygwin app via LoadLibrary.  */
719 void
720 dll_crt0_1 (void *)
721 {
722   extern void initial_setlocale ();
723
724   if (dynamically_loaded)
725     sigproc_init ();
726
727   check_sanity_and_sync (user_data);
728
729   /* Initialize malloc and then call user_shared_initialize since it relies
730      on a functioning malloc and it's possible that the user's program may
731      have overridden malloc.  We only know about that at this stage,
732      unfortunately. */
733   malloc_init ();
734   user_shared->initialize ();
735
736 #ifdef CYGHEAP_DEBUG
737   int i = 0;
738   const int n = 2 * 1024 * 1024;
739   while (i--)
740     {
741       void *p = cmalloc (HEAP_STR, n);
742       if (p)
743         small_printf ("cmalloc returns %p\n", cmalloc (HEAP_STR, n));
744       else
745         {
746           small_printf ("total allocated %p\n", (i - 1) * n);
747           break;
748         }
749     }
750 #endif
751
752   ProtectHandle (hMainThread);
753
754   cygheap->cwd.init ();
755
756   /* Initialize pthread mainthread when not forked and it is safe to call new,
757      otherwise it is reinitalized in fixup_after_fork */
758   if (!in_forkee)
759     {
760       pthread::init_mainthread ();
761       _pei386_runtime_relocator (user_data);
762     }
763
764 #ifdef DEBUGGING
765   strace.microseconds ();
766 #endif
767
768   create_signal_arrived (); /* FIXME: move into wait_sig? */
769
770   /* Initialize debug muto, if DLL is built with --enable-debugging.
771      Need to do this before any helper threads start. */
772   debug_init ();
773
774 #ifdef NEWVFORK
775   cygheap->fdtab.vfork_child_fixup ();
776   main_vfork = vfork_storage.create ();
777 #endif
778
779   cygbench ("pre-forkee");
780   if (in_forkee)
781     {
782       /* If we've played with the stack, stacksize != 0.  That means that
783          fork() was invoked from other than the main thread.  Make sure that
784          frame pointer is referencing the new stack so that the OS knows what
785          to do when it needs to increase the size of the stack.
786
787          NOTE: Don't do anything that involves the stack until you've completed
788          this step. */
789       if (fork_info->stackaddr)
790         {
791           _tlsbase = (char *) fork_info->stackbottom;
792           _tlstop = (char *) fork_info->stacktop;
793         }
794
795       longjmp (fork_info->jmp, true);
796     }
797
798   __sinit (_impure_ptr);
799
800 #ifdef DEBUGGING
801   {
802   extern void fork_init ();
803   fork_init ();
804   }
805 #endif
806   pinfo_init (envp, envc);
807   strace.dll_info ();
808
809   /* Allocate cygheap->fdtab */
810   dtable_init ();
811
812   uinfo_init ();        /* initialize user info */
813
814   /* Connect to tty. */
815   tty::init_session ();
816
817   /* Set internal locale to the environment settings. */
818   initial_setlocale ();
819
820   if (!__argc)
821     {
822       PWCHAR wline = GetCommandLineW ();
823       size_t size = sys_wcstombs (NULL, 0, wline);
824       char *line = (char *) alloca (size);
825       sys_wcstombs (line, size, wline);
826
827       /* Scan the command line and build argv.  Expand wildcards if not
828          called from another cygwin process. */
829       build_argv (line, __argv, __argc,
830                   NOTSTATE (myself, PID_CYGPARENT) && allow_glob);
831
832       /* Convert argv[0] to posix rules if it's currently blatantly
833          win32 style. */
834       if ((strchr (__argv[0], ':')) || (strchr (__argv[0], '\\')))
835         {
836           char *new_argv0 = (char *) malloc (NT_MAX_PATH);
837           cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_RELATIVE, __argv[0],
838                             new_argv0, NT_MAX_PATH);
839           __argv[0] = (char *) realloc (new_argv0, strlen (new_argv0) + 1);
840         }
841     }
842
843   __argc_safe = __argc;
844   if (user_data->premain[0])
845     for (unsigned int i = 0; i < PREMAIN_LEN / 2; i++)
846       user_data->premain[i] (__argc, __argv, user_data);
847
848   /* Set up standard fds in file descriptor table. */
849   cygheap->fdtab.stdio_init ();
850
851   /* Set up __progname for getopt error call. */
852   if (__argv[0] && (__progname = strrchr (__argv[0], '/')))
853     ++__progname;
854   else
855     __progname = __argv[0];
856   program_invocation_name = __argv[0];
857   program_invocation_short_name = __progname;
858   if (__progname)
859     {
860       char *cp = strchr (__progname, '\0') - 4;
861       if (cp > __progname && ascii_strcasematch (cp, ".exe"))
862         *cp = '\0';
863     }
864
865   (void) xdr_set_vprintf (&cygxdr_vwarnx);
866   cygwin_finished_initializing = true;
867   /* Call init of loaded dlls. */
868   dlls.init ();
869
870   /* Execute any specified "premain" functions */
871   if (user_data->premain[PREMAIN_LEN / 2])
872     for (unsigned int i = PREMAIN_LEN / 2; i < PREMAIN_LEN; i++)
873       user_data->premain[i] (__argc, __argv, user_data);
874
875   set_errno (0);
876
877   if (dynamically_loaded)
878     {
879       _setlocale_r (_REENT, LC_CTYPE, "C");
880       return;
881     }
882
883   /* Disable case-insensitive globbing */
884   ignore_case_with_glob = false;
885
886   MALLOC_CHECK;
887   cygbench (__progname);
888
889   ld_preload ();
890   /* Per POSIX set the default application locale back to "C". */
891   _setlocale_r (_REENT, LC_CTYPE, "C");
892
893   if (user_data->main)
894     {
895       /* Create a copy of Cygwin's version of __argv so that, if the user makes
896          a change to an element of argv[] it does not affect Cygwin's argv.
897          Changing the the contents of what argv[n] points to will still
898          affect Cygwin.  This is similar (but not exactly like) Linux. */
899       char *newargv[__argc + 1];
900       char **nav = newargv;
901       char **oav = __argv;
902       while ((*nav++ = *oav++) != NULL)
903         continue;
904       cygwin_exit (user_data->main (__argc, newargv, *user_data->envptr));
905     }
906   __asm__ ("                            \n\
907         .global __cygwin_exit_return    \n\
908 __cygwin_exit_return:                   \n\
909 ");
910 }
911
912 extern "C" void __stdcall
913 _dll_crt0 ()
914 {
915 #ifdef __i386__
916   _feinitialise ();
917 #endif
918   main_environ = user_data->envptr;
919   if (in_forkee)
920     {
921       fork_info->alloc_stack ();
922       _main_tls = &_my_tls;
923     }
924
925   _main_tls->call ((DWORD (*) (void *, void *)) dll_crt0_1, NULL);
926 }
927
928 void
929 dll_crt0 (per_process *uptr)
930 {
931   /* Set the local copy of the pointer into the user space. */
932   if (!in_forkee && uptr && uptr != user_data)
933     {
934       memcpy (user_data, uptr, per_process_overwrite);
935       *(user_data->impure_ptr_ptr) = _GLOBAL_REENT;
936     }
937   _dll_crt0 ();
938 }
939
940 /* This must be called by anyone who uses LoadLibrary to load cygwin1.dll.
941    You must have CYGTLS_PADSIZE bytes reserved at the bottom of the stack
942    calling this function, and that storage must not be overwritten until you
943    unload cygwin1.dll, as it is used for _my_tls.  It is best to load
944    cygwin1.dll before spawning any additional threads in your process.
945
946    See winsup/testsuite/cygload for an example of how to use cygwin1.dll
947    from MSVC and non-cygwin MinGW applications.  */
948 extern "C" void
949 cygwin_dll_init ()
950 {
951   static char **envp;
952   static int _fmode;
953
954   user_data->magic_biscuit = sizeof (per_process);
955
956   user_data->envptr = &envp;
957   user_data->fmode_ptr = &_fmode;
958
959   _dll_crt0 ();
960 }
961
962 extern "C" void
963 __main (void)
964 {
965   /* Ordering is critical here.  DLL ctors have already been
966      run as they were being loaded, so we should stack the
967      queued call to DLL dtors now.  */
968   atexit (dll_global_dtors);
969   do_global_ctors (user_data->ctors, false);
970   /* Now we have run global ctors, register their dtors.
971
972      At exit, global dtors will run first, so the app can still
973      use shared library functions while terminating; then the
974      DLLs will be destroyed; finally newlib will shut down stdio
975      and terminate itself.  */
976   atexit (do_global_dtors);
977   sig_dispatch_pending (true);
978 }
979
980 void __stdcall
981 do_exit (int status)
982 {
983   syscall_printf ("do_exit (%d), exit_state %d", status, exit_state);
984
985 #ifdef NEWVFORK
986   vfork_save *vf = vfork_storage.val ();
987   if (vf != NULL && vf->pid < 0)
988     {
989       exit_state = ES_NOT_EXITING;
990       vf->restore_exit (status);
991     }
992 #endif
993
994   lock_process until_exit (true);
995
996   if (exit_state < ES_EVENTS_TERMINATE)
997     {
998       exit_state = ES_EVENTS_TERMINATE;
999       events_terminate ();
1000     }
1001
1002   if (exit_state < ES_SIGNAL)
1003     {
1004       exit_state = ES_SIGNAL;
1005       signal (SIGCHLD, SIG_IGN);
1006       signal (SIGHUP, SIG_IGN);
1007       signal (SIGINT, SIG_IGN);
1008       signal (SIGQUIT, SIG_IGN);
1009     }
1010
1011   if (exit_state < ES_CLOSEALL)
1012     {
1013       exit_state = ES_CLOSEALL;
1014       close_all_files ();
1015     }
1016
1017   UINT n = (UINT) status;
1018   if (exit_state < ES_THREADTERM)
1019     {
1020       exit_state = ES_THREADTERM;
1021       cygthread::terminate ();
1022     }
1023
1024   myself->stopsig = 0;
1025
1026   if (exit_state < ES_HUP_PGRP)
1027     {
1028       exit_state = ES_HUP_PGRP;
1029       /* Kill orphaned children on group leader exit */
1030       if (myself->has_pgid_children && myself->pid == myself->pgid)
1031         {
1032           siginfo_t si = {0};
1033           si.si_signo = -SIGHUP;
1034           si.si_code = SI_KERNEL;
1035           sigproc_printf ("%d == pgrp %d, send SIG{HUP,CONT} to stopped children",
1036                           myself->pid, myself->pgid);
1037           kill_pgrp (myself->pgid, si);
1038         }
1039     }
1040
1041   if (exit_state < ES_HUP_SID)
1042     {
1043       exit_state = ES_HUP_SID;
1044       /* Kill the foreground process group on session leader exit */
1045       if (getpgrp () > 0 && myself->pid == myself->sid && real_tty_attached (myself))
1046         {
1047           tty *tp = cygwin_shared->tty[myself->ctty];
1048           sigproc_printf ("%d == sid %d, send SIGHUP to children",
1049                           myself->pid, myself->sid);
1050
1051         /* CGF FIXME: This can't be right. */
1052           if (tp->getsid () == myself->sid)
1053             tp->kill_pgrp (SIGHUP);
1054         }
1055
1056     }
1057
1058   myself.exit (n);
1059 }
1060
1061 extern "C" int
1062 cygwin_atexit (void (*fn) (void))
1063 {
1064   int res;
1065   dll *d = dlls.find ((void *) _my_tls.retaddr ());
1066   res = d ? __cxa_atexit ((void (*) (void *)) fn, NULL, d) : atexit (fn);
1067   return res;
1068 }
1069
1070 extern "C" void
1071 cygwin_exit (int n)
1072 {
1073   exit_state = ES_EXIT_STARTING;
1074   exit (n);
1075 }
1076
1077 extern "C" void
1078 _exit (int n)
1079 {
1080   do_exit (((DWORD) n & 0xff) << 8);
1081 }
1082
1083 extern "C" void cygwin_stackdump ();
1084
1085 extern "C" void
1086 vapi_fatal (const char *fmt, va_list ap)
1087 {
1088   char buf[4096];
1089   int n = __small_sprintf (buf, "%P: *** fatal error %s- ", in_forkee ? "in forked process " : "");
1090   __small_vsprintf (buf + n, fmt, ap);
1091   va_end (ap);
1092   strace.prntf (_STRACE_SYSTEM, NULL, "%s", buf);
1093
1094 #ifdef DEBUGGING
1095   try_to_debug ();
1096 #endif
1097   cygwin_stackdump ();
1098   myself.exit (__api_fatal_exit_val);
1099 }
1100
1101 extern "C" void
1102 api_fatal (const char *fmt, ...)
1103 {
1104   va_list ap;
1105
1106   va_start (ap, fmt);
1107   vapi_fatal (fmt, ap);
1108 }
1109
1110 void
1111 multiple_cygwin_problem (const char *what, unsigned magic_version, unsigned version)
1112 {
1113   if (_cygwin_testing && (strstr (what, "proc") || strstr (what, "cygheap")))
1114     {
1115       child_proc_info->type = _CH_WHOOPS;
1116       return;
1117     }
1118
1119   if (GetEnvironmentVariableA ("CYGWIN_MISMATCH_OK", NULL, 0))
1120     return;
1121
1122   if (CYGWIN_VERSION_MAGIC_VERSION (magic_version) == version)
1123     system_printf ("%s magic number mismatch detected - %p/%p", what, magic_version, version);
1124   else
1125     api_fatal ("%s mismatch detected - %p/%p.\n\
1126 This problem is probably due to using incompatible versions of the cygwin DLL.\n\
1127 Search for cygwin1.dll using the Windows Start->Find/Search facility\n\
1128 and delete all but the most recent version.  The most recent version *should*\n\
1129 reside in x:\\cygwin\\bin, where 'x' is the drive on which you have\n\
1130 installed the cygwin distribution.  Rebooting is also suggested if you\n\
1131 are unable to find another cygwin DLL.",
1132                what, magic_version, version);
1133 }
1134
1135 #ifdef DEBUGGING
1136 void __stdcall
1137 cygbench (const char *s)
1138 {
1139   if (GetEnvironmentVariableA ("CYGWIN_BENCH", NULL, 0))
1140     small_printf ("%05d ***** %s : %10d\n", GetCurrentProcessId (), s, strace.microseconds ());
1141 }
1142 #endif