OSDN Git Service

* fhandler.h (fhandler_console): Remove tcsetpgrp.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / fork.cc
1 /* fork.cc
2
3    Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
4
5 This file is part of Cygwin.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
11 #include "winsup.h"
12 #include <stdio.h>
13 #include <unistd.h>
14 #include <stdlib.h>
15 #include <fcntl.h>
16 #include <stdarg.h>
17 #include <errno.h>
18 #include "fhandler.h"
19 #include "dtable.h"
20 #include "cygerrno.h"
21 #include "sync.h"
22 #include "sigproc.h"
23 #include "pinfo.h"
24 #include "cygheap.h"
25 #include "child_info.h"
26 #define NEED_VFORK
27 #include "perthread.h"
28 #include "perprocess.h"
29 #include "dll_init.h"
30 #include "security.h"
31
32 DWORD NO_COPY chunksize = 0;
33 /* Timeout to wait for child to start, parent to init child, etc.  */
34 /* FIXME: Once things stabilize, bump up to a few minutes.  */
35 #define FORK_WAIT_TIMEOUT (300 * 1000)     /* 300 seconds */
36
37 #define dll_data_start &_data_start__
38 #define dll_data_end &_data_end__
39 #define dll_bss_start &_bss_start__
40 #define dll_bss_end &_bss_end__
41
42 void
43 per_thread::set (void *s)
44 {
45   if (s == PER_THREAD_FORK_CLEAR)
46     {
47       tls = TlsAlloc ();
48       s = NULL;
49     }
50   TlsSetValue (get_tls (), s);
51 }
52
53 static void
54 stack_base (child_info_fork &ch)
55 {
56   MEMORY_BASIC_INFORMATION m;
57   memset (&m, 0, sizeof m);
58   if (!VirtualQuery ((LPCVOID) &m, &m, sizeof m))
59     system_printf ("couldn't get memory info, %E");
60
61   ch.stacktop = m.AllocationBase;
62   ch.stackbottom = (LPBYTE) m.BaseAddress + m.RegionSize;
63   ch.stacksize = (DWORD) ch.stackbottom - (DWORD) &m;
64   debug_printf ("bottom %p, top %p, stack %p, size %d, reserve %d",
65                 ch.stackbottom, ch.stacktop, &m, ch.stacksize,
66                 (DWORD) ch.stackbottom - (DWORD) ch.stacktop);
67 }
68
69 /* Copy memory from parent to child.
70    The result is a boolean indicating success.  */
71
72 static int
73 fork_copy (PROCESS_INFORMATION &pi, const char *what, ...)
74 {
75   va_list args;
76   char *low;
77   int pass = 0;
78
79   va_start (args, what);
80
81   while ((low = va_arg (args, char *)))
82     {
83       char *high = va_arg (args, char *);
84       DWORD todo = chunksize ?: high - low;
85       char *here;
86
87       for (here = low; here < high; here += todo)
88         {
89           DWORD done = 0;
90           if (here + todo > high)
91             todo = high - here;
92           int res = WriteProcessMemory (pi.hProcess, here, here, todo, &done);
93           debug_printf ("child handle %p, low %p, high %p, res %d", pi.hProcess,
94                         low, high, res);
95           if (!res || todo != done)
96             {
97               if (!res)
98                 __seterrno ();
99               /* If this happens then there is a bug in our fork
100                  implementation somewhere. */
101               system_printf ("%s pass %d failed, %p..%p, done %d, %E",
102                             what, pass, low, high, done);
103               goto err;
104             }
105         }
106
107       pass++;
108     }
109
110   debug_printf ("done");
111   return 1;
112
113 err:
114   TerminateProcess (pi.hProcess, 1);
115   set_errno (EAGAIN);
116   return 0;
117 }
118
119 /* Wait for child to finish what it's doing and signal us.
120    We don't want to wait forever here.If there's a problem somewhere
121    it'll hang the entire system (since all forks are mutex'd). If we
122    time out, set errno = EAGAIN and hope the app tries again.  */
123 static int
124 sync_with_child (PROCESS_INFORMATION &pi, HANDLE subproc_ready,
125                  BOOL hang_child, const char *s)
126 {
127   /* We also add the child process handle to the wait. If the child fails
128      to initialize (eg. because of a missing dll). Then this
129      handle will become signalled. This stops a *looong* timeout wait.
130   */
131   HANDLE w4[2];
132
133   debug_printf ("waiting for child.  reason: %s, hang_child %d", s,
134                 hang_child);
135   w4[1] = pi.hProcess;
136   w4[0] = subproc_ready;
137   DWORD rc = WaitForMultipleObjects (2, w4, FALSE, FORK_WAIT_TIMEOUT);
138
139   if (rc == WAIT_OBJECT_0 ||
140       WaitForSingleObject (subproc_ready, 0) == WAIT_OBJECT_0)
141     /* That's ok */;
142   else if (rc == WAIT_FAILED || rc == WAIT_TIMEOUT)
143     {
144       if (rc != WAIT_FAILED)
145         system_printf ("WaitForMultipleObjects timed out");
146       else
147         system_printf ("WaitForMultipleObjects failed, %E");
148       set_errno (EAGAIN);
149       syscall_printf ("-1 = fork(), WaitForMultipleObjects failed");
150       TerminateProcess (pi.hProcess, 1);
151       return 0;
152     }
153   else
154     {
155       /* Child died. Clean up and exit. */
156       DWORD errcode;
157       GetExitCodeProcess (pi.hProcess, &errcode);
158       /* Fix me.  This is not enough.  The fork should not be considered
159        * to have failed if the process was essentially killed by a signal.
160        */
161       if (errcode != STATUS_CONTROL_C_EXIT)
162         {
163             system_printf ("child %d(%p) died before initialization with status code %p",
164                           pi.dwProcessId, pi.hProcess, errcode);
165             system_printf ("*** child state %s", s);
166 #ifdef DEBUGGING
167             abort ();
168 #endif
169         }
170       set_errno (EAGAIN);
171       syscall_printf ("Child died before subproc_ready signalled");
172       return 0;
173     }
174
175   debug_printf ("child signalled me");
176   return 1;
177 }
178
179 static int
180 resume_child (PROCESS_INFORMATION &pi, HANDLE forker_finished)
181 {
182   SetEvent (forker_finished);
183   debug_printf ("signalled child");
184   return 1;
185 }
186
187 /* Notify parent that it is time for the next step.
188    Note that this has to be a macro since the parent may be messing with
189    our stack. */
190 static void __stdcall
191 sync_with_parent(const char *s, bool hang_self)
192 {
193   debug_printf ("signalling parent: %s", s);
194   /* Tell our parent we're waiting. */
195   if (!SetEvent (child_proc_info->subproc_ready))
196     api_fatal ("fork child - SetEvent failed, %E");
197   if (hang_self)
198     {
199       HANDLE h = child_proc_info->forker_finished;
200       /* Wait for the parent to fill in our stack and heap.
201          Don't wait forever here.  If our parent dies we don't want to clog
202          the system.  If the wait fails, we really can't continue so exit.  */
203       DWORD psync_rc = WaitForSingleObject (h, FORK_WAIT_TIMEOUT);
204       debug_printf ("awake");
205       switch (psync_rc)
206         {
207         case WAIT_TIMEOUT:
208           api_fatal ("WFSO timed out");
209           break;
210         case WAIT_FAILED:
211           if (GetLastError () == ERROR_INVALID_HANDLE &&
212               WaitForSingleObject (child_proc_info->forker_finished, 1) != WAIT_FAILED)
213             break;
214           api_fatal ("WFSO failed, fork_finished %p, %E", child_proc_info->forker_finished);
215           break;
216         default:
217           debug_printf ("no problems");
218           break;
219         }
220     }
221 }
222
223 static int __stdcall
224 fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
225 {
226   debug_printf ("child is running.  pid %d, ppid %d, stack here %p",
227                 myself->pid, myself->ppid, __builtin_frame_address (0));
228
229   /* Restore the inheritance state as in parent
230      Don't call setuid here! The flags are already set. */
231   if (myself->impersonated)
232     {
233       debug_printf ("Impersonation of child, token: %d", myself->token);
234       if (myself->token == INVALID_HANDLE_VALUE)
235         RevertToSelf (); // probably not needed
236       else if (!ImpersonateLoggedOnUser (myself->token))
237         system_printf ("Impersonate for forked child failed: %E");
238     }
239
240   sync_with_parent ("after longjmp.", TRUE);
241   ProtectHandle (hParent);
242   sigproc_printf ("hParent %p, child 1 first_dll %p, load_dlls %d\n", hParent, first_dll, load_dlls);
243
244 #ifdef DEBUGGING
245   char c;
246   if (GetEnvironmentVariable ("FORKDEBUG", &c, 1))
247     try_to_debug ();
248   char buf[80];
249   /* This is useful for debugging fork problems.  Use gdb to attach to
250      the pid reported here. */
251   if (GetEnvironmentVariable ("CYGWIN_FORK_SLEEP", buf, sizeof (buf)))
252     {
253       small_printf ("Sleeping %d after fork, pid %u\n", atoi (buf), GetCurrentProcessId ());
254       Sleep (atoi(buf));
255     }
256 #endif
257
258   /* If we've played with the stack, stacksize != 0.  That means that
259      fork() was invoked from other than the main thread.  Make sure that
260      when the "main" thread exits it calls do_exit, like a normal process.
261      Exit with a status code of 0. */
262   if (child_proc_info->stacksize)
263     {
264       ((DWORD *)child_proc_info->stackbottom)[-17] = (DWORD)do_exit;
265       ((DWORD *)child_proc_info->stackbottom)[-15] = (DWORD)0;
266     }
267
268   MALLOC_CHECK;
269
270   pinfo_fixup_after_fork ();
271   fdtab.fixup_after_fork (hParent);
272   signal_fixup_after_fork ();
273
274   MALLOC_CHECK;
275
276   /* If we haven't dynamically loaded any dlls, just signal
277      the parent.  Otherwise, load all the dlls, tell the parent
278       that we're done, and wait for the parent to fill in the.
279       loaded dlls' data/bss. */
280   if (!load_dlls)
281     sync_with_parent ("performed fork fixup.", FALSE);
282   else
283     {
284       dlls.load_after_fork (hParent, first_dll);
285       sync_with_parent ("loaded dlls", TRUE);
286     }
287
288   ForceCloseHandle (hParent);
289   (void) ForceCloseHandle (child_proc_info->subproc_ready);
290   (void) ForceCloseHandle (child_proc_info->forker_finished);
291
292   if (recreate_mmaps_after_fork (myself->mmap_ptr))
293     api_fatal ("recreate_mmaps_after_fork_failed");
294
295   /* Set thread local stuff to zero.  Under Windows 95/98 this is sometimes
296      non-zero, for some reason.
297      FIXME:  There is a memory leak here after a fork. */
298   for (per_thread **t = threadstuff; *t; t++)
299     if ((*t)->clear_on_fork ())
300       (*t)->set ();
301
302   /* Initialize signal/process handling */
303   sigproc_init ();
304   cygbench ("fork-child");
305   return 0;
306 }
307
308 static int __stdcall
309 fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls, child_info_fork &ch)
310 {
311   HANDLE subproc_ready, forker_finished;
312   DWORD rc;
313   PROCESS_INFORMATION pi = {0, NULL, 0, 0};
314   static NO_COPY HANDLE last_fork_proc = NULL;
315
316   subproc_init ();
317
318 #ifdef DEBUGGING
319   /* The ProtectHandle call allocates memory so we need to make sure
320      that enough is set aside here so that the sbrk pointer does not
321      move when ProtectHandle is called after the child is started.
322      Otherwise the sbrk pointers in the parent will not agree with
323      the child and when user_data is (regrettably) copied over,
324      the user_data->ptr field will not be accurate. */
325   free (malloc (4096));
326 #endif
327
328   int c_flags = GetPriorityClass (hMainProc) /*|
329                 CREATE_NEW_PROCESS_GROUP*/;
330   STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
331
332   /* If we don't have a console, then don't create a console for the
333      child either.  */
334   HANDLE console_handle = CreateFileA ("CONOUT$", GENERIC_WRITE,
335                                        FILE_SHARE_WRITE, &sec_none_nih,
336                                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
337                                        NULL);
338
339   if (console_handle != INVALID_HANDLE_VALUE && console_handle != 0)
340     CloseHandle (console_handle);
341   else
342     c_flags |= DETACHED_PROCESS;
343
344   hParent = NULL;
345   if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hParent, 0, 1,
346                         DUPLICATE_SAME_ACCESS))
347     {
348       system_printf ("couldn't create handle to myself for child, %E");
349       return -1;
350     }
351
352   /* Remember the address of the first loaded dll and decide
353      if we need to load dlls.  We do this here so that this
354      information will be available in the parent and, when
355      the stack is copied, in the child. */
356   first_dll = dlls.start.next;
357   load_dlls = dlls.reload_on_fork && dlls.loaded_dlls;
358
359   /* This will help some of the confusion.  */
360   fflush (stdout);
361
362   subproc_ready = CreateEvent (&sec_all, FALSE, FALSE, NULL);
363   if (subproc_ready == NULL)
364     {
365       CloseHandle (hParent);
366       system_printf ("unable to allocate subproc_ready event, %E");
367       return -1;
368     }
369   forker_finished = CreateEvent (&sec_all, FALSE, FALSE, NULL);
370   if (forker_finished == NULL)
371     {
372       CloseHandle (hParent);
373       CloseHandle (subproc_ready);
374       system_printf ("unable to allocate subproc_ready event, %E");
375       return -1;
376     }
377
378   ProtectHandle (subproc_ready);
379   ProtectHandle (forker_finished);
380
381   init_child_info (PROC_FORK1, &ch, 1, subproc_ready);
382
383   ch.forker_finished = forker_finished;
384   ch.heaptop = user_data->heaptop;
385   ch.heapbase = user_data->heapbase;
386   ch.heapptr = user_data->heapptr;
387
388   stack_base (ch);
389
390   si.cb = sizeof (STARTUPINFO);
391   si.lpReserved2 = (LPBYTE)&ch;
392   si.cbReserved2 = sizeof(ch);
393
394   /* Remove impersonation */
395   uid_t uid;
396   uid = geteuid();
397   if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
398     seteuid (myself->orig_uid);
399
400   ch.parent = hParent;
401   ch.cygheap = cygheap;
402   ch.cygheap_max = cygheap_max;
403
404   char sa_buf[1024];
405   syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
406                   myself->progname, myself->progname, c_flags, &si, &pi);
407   rc = CreateProcess (myself->progname, /* image to run */
408                       myself->progname, /* what we send in arg0 */
409                       allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
410                       allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
411                       TRUE,       /* inherit handles from parent */
412                       c_flags,
413                       NULL,       /* environment filled in later */
414                       0,                  /* use current drive/directory */
415                       &si,
416                       &pi);
417
418   CloseHandle (hParent);
419
420   if (!rc)
421     {
422       __seterrno ();
423       syscall_printf ("CreateProcessA failed, %E");
424       ForceCloseHandle(subproc_ready);
425       ForceCloseHandle(forker_finished);
426       /* Restore impersonation */
427       if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
428         seteuid (uid);
429       return -1;
430     }
431
432   pinfo forked (cygwin_pid (pi.dwProcessId), 1);
433
434   /* Initialize things that are done later in dll_crt0_1 that aren't done
435      for the forkee.  */
436   strcpy(forked->progname, myself->progname);
437
438   /* Restore impersonation */
439   if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
440     seteuid (uid);
441
442   ProtectHandle (pi.hThread);
443   /* Protect the handle but name it similarly to the way it will
444      be called in subproc handling. */
445   ProtectHandle1 (pi.hProcess, childhProc);
446
447   /* Keep a handle to the current forked process sitting around to prevent
448      Windows from reusing the same pid twice in a row.  Having the same pid
449      twice in a row confuses bash.  So, after every CreateProcess, we can safely
450      remove the old pid and save a handle to the newly created process.  Keeping
451      a handle open will stop windows from reusing the same pid.  */
452   if (last_fork_proc)
453     CloseHandle (last_fork_proc);
454   if (!DuplicateHandle (hMainProc, pi.hProcess, hMainProc, &last_fork_proc,
455                         0, FALSE, DUPLICATE_SAME_ACCESS))
456     system_printf ("couldn't create last_fork_proc, %E");
457
458   /* Fill in fields in the child's process table entry.  */
459   forked->ppid = myself->pid;
460   forked->hProcess = pi.hProcess;
461   forked->dwProcessId = pi.dwProcessId;
462   forked->uid = myself->uid;
463   forked->gid = myself->gid;
464   forked->pgid = myself->pgid;
465   forked->sid = myself->sid;
466   forked->ctty = myself->ctty;
467   forked->umask = myself->umask;
468   forked->copysigs(myself);
469   forked->process_state |= PID_INITIALIZING |
470                           (myself->process_state & PID_USETTY);
471   memcpy (forked->username, myself->username, MAX_USER_NAME);
472   if (myself->use_psid)
473     {
474       memcpy (forked->psid, myself->psid, MAX_SID_LEN);
475       forked->use_psid = 1;
476     }
477   memcpy (forked->logsrv, myself->logsrv, MAX_HOST_NAME);
478   memcpy (forked->domain, myself->domain, MAX_COMPUTERNAME_LENGTH+1);
479   forked->token = myself->token;
480   forked->impersonated = myself->impersonated;
481   forked->orig_uid = myself->orig_uid;
482   forked->orig_gid = myself->orig_gid;
483   forked->real_uid = myself->real_uid;
484   forked->real_gid = myself->real_gid;
485   strcpy (forked->root, myself->root);
486   forked->rootlen = myself->rootlen;
487   set_child_mmap_ptr (forked);
488
489   /* Wait for subproc to initialize itself. */
490   if (!sync_with_child(pi, subproc_ready, TRUE, "waiting for longjmp"))
491     goto cleanup;
492
493   /* CHILD IS STOPPED */
494   debug_printf ("child is alive (but stopped)");
495
496   /* Initialize, in order: data, bss, heap, stack, dll data, dll bss
497      Note: variables marked as NO_COPY will not be copied
498      since they are placed in a protected segment. */
499
500
501   MALLOC_CHECK;
502   rc = fork_copy (pi, "user/cygwin data",
503                   user_data->data_start, user_data->data_end,
504                   user_data->bss_start, user_data->bss_end,
505                   ch.heapbase, ch.heapptr,
506                   stack_here, ch.stackbottom,
507                   dll_data_start, dll_data_end,
508                   dll_bss_start, dll_bss_end, NULL);
509
510   MALLOC_CHECK;
511   if (!rc)
512     goto cleanup;
513
514   /* Now fill data/bss of any DLLs that were linked into the program. */
515   for (dll *d = dlls.istart (DLL_LINK); d; d = dlls.inext ())
516     {
517       debug_printf ("copying data/bss of a linked dll");
518       if (!fork_copy (pi, "linked dll data/bss", d->p.data_start, d->p.data_end,
519                                                  d->p.bss_start, d->p.bss_end,
520                                                  NULL))
521         goto cleanup;
522     }
523
524   forked.remember ();
525
526   /* Start thread, and wait for it to reload dlls.  */
527   if (!resume_child (pi, forker_finished) ||
528       !sync_with_child (pi, subproc_ready, load_dlls, "child loading dlls"))
529     goto cleanup;
530
531   /* If DLLs were loaded in the parent, then the child has reloaded all
532      of them and is now waiting to have all of the individual data and
533      bss sections filled in. */
534   if (load_dlls)
535     {
536       /* CHILD IS STOPPED */
537       /* write memory of reloaded dlls */
538       for (dll *d = dlls.istart (DLL_LOAD); d; d = dlls.inext ())
539         {
540           debug_printf ("copying data/bss for a loaded dll");
541           if (!fork_copy (pi, "loaded dll data/bss", d->p.data_start, d->p.data_end,
542                                                      d->p.bss_start, d->p.bss_end,
543                                                      NULL))
544             goto cleanup;
545         }
546       /* Start the child up again. */
547       (void) resume_child (pi, forker_finished);
548     }
549
550   ForceCloseHandle (subproc_ready);
551   ForceCloseHandle (pi.hThread);
552   ForceCloseHandle (forker_finished);
553   forker_finished = NULL;
554   pi.hThread = NULL;
555
556   return forked->pid;
557
558 /* Common cleanup code for failure cases */
559 cleanup:
560   /* Remember to de-allocate the fd table. */
561   if (pi.hProcess)
562     ForceCloseHandle1 (pi.hProcess, childhProc);
563   if (pi.hThread)
564     ForceCloseHandle (pi.hThread);
565   if (subproc_ready)
566     ForceCloseHandle (subproc_ready);
567   if (forker_finished)
568     ForceCloseHandle (forker_finished);
569   return -1;
570 }
571
572 extern "C" int
573 fork ()
574 {
575   struct
576   {
577     HANDLE hParent;
578     dll *first_dll;
579     bool load_dlls;
580   } grouped;
581
582   MALLOC_CHECK;
583
584   debug_printf ("entering");
585   grouped.hParent = grouped.first_dll = NULL;
586   grouped.load_dlls = 0;
587
588   if (ISSTATE(myself, PID_SPLIT_HEAP))
589     {
590       system_printf ("The heap has been split, CYGWIN can't fork this process.");
591       system_printf ("Increase the heap_chunk_size in the registry and try again.");
592       set_errno (ENOMEM);
593       syscall_printf ("-1 = fork (), split heap");
594       return -1;
595     }
596
597   void *esp;
598   __asm ("movl %%esp,%0": "=r" (esp));
599
600   child_info_fork ch;
601
602   int res = setjmp (ch.jmp);
603
604   if (res)
605     res = fork_child (grouped.hParent, grouped.first_dll, grouped.load_dlls);
606   else
607     res = fork_parent (esp, grouped.hParent, grouped.first_dll, grouped.load_dlls, ch);
608
609   MALLOC_CHECK;
610   syscall_printf ("%d = fork()", res);
611   return res;
612 }
613
614 #ifdef NEWVFORK
615 /* Dummy function to force second assignment below to actually be
616    carried out */
617 static vfork_save *
618 get_vfork_val ()
619 {
620   return vfork_storage.val ();
621 }
622 #endif
623
624 extern "C"
625 int
626 vfork ()
627 {
628 #ifndef NEWVFORK
629   return fork ();
630 #else
631   vfork_save *vf = get_vfork_val ();
632   char **esp, **pp;
633
634   if (vf == NULL)
635     vf = vfork_storage.create ();
636
637   if (!setjmp (vf->j))
638     {
639       vf->pid = -1;
640       __asm__ volatile ("movl %%esp,%0": "=r" (vf->vfork_esp):);
641       __asm__ volatile ("movl %%ebp,%0": "=r" (vf->vfork_ebp):);
642       for (pp = (char **)vf->frame, esp = vf->vfork_esp;
643            esp <= vf->vfork_ebp + 1; pp++, esp++)
644         *pp = *esp;
645       return fdtab.vfork_child_dup () ? 0 : -1;
646     }
647
648   fdtab.vfork_parent_restore ();
649
650   vf = get_vfork_val ();
651   if (vf->pid < 0)
652     {
653       int exitval = -vf->pid;
654       if ((vf->pid = fork ()) == 0)
655         exit (exitval);
656     }
657
658   __asm__ volatile ("movl %%esp,%0": "=r" (esp):);
659   for (pp = (char **)vf->frame, esp = vf->vfork_esp;
660        esp <= vf->vfork_ebp + 1; pp++, esp++)
661     *esp = *pp;
662
663   return vf->pid;
664 #endif
665 }