OSDN Git Service

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