3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
25 #include "child_info.h"
27 #include "perprocess.h"
30 #include "shared_info.h"
31 #include "cygmalloc.h"
32 #include "cygthread.h"
36 /* Timeout to wait for child to start, parent to init child, etc. */
37 /* FIXME: Once things stabilize, bump up to a few minutes. */
38 #define FORK_WAIT_TIMEOUT (300 * 1000) /* 300 seconds */
40 #define dll_data_start &_data_start__
41 #define dll_data_end &_data_end__
42 #define dll_bss_start &_bss_start__
43 #define dll_bss_end &_bss_end__
46 stack_base (child_info_fork &ch)
48 MEMORY_BASIC_INFORMATION m;
49 memset (&m, 0, sizeof m);
50 if (!VirtualQuery ((LPCVOID) &m, &m, sizeof m))
51 system_printf ("couldn't get memory info, %E");
53 ch.stacktop = m.AllocationBase;
54 ch.stackbottom = (LPBYTE) m.BaseAddress + m.RegionSize;
55 ch.stacksize = (DWORD) ch.stackbottom - (DWORD) &m;
56 debug_printf ("bottom %p, top %p, stack %p, size %d, reserve %d",
57 ch.stackbottom, ch.stacktop, &m, ch.stacksize,
58 (DWORD) ch.stackbottom - (DWORD) ch.stacktop);
61 /* Copy memory from parent to child.
62 The result is a boolean indicating success. */
65 fork_copy (PROCESS_INFORMATION &pi, const char *what, ...)
71 va_start (args, what);
73 while ((low = va_arg (args, char *)))
75 char *high = va_arg (args, char *);
76 DWORD todo = wincap.chunksize () ?: high - low;
79 for (here = low; here < high; here += todo)
82 if (here + todo > high)
86 res = WriteProcessMemory (pi.hProcess, here, here, todo, &done);
88 res = ReadProcessMemory (pi.hProcess, here, here, todo, &done);
89 debug_printf ("child handle %p, low %p, high %p, res %d", pi.hProcess,
91 if (!res || todo != done)
95 /* If this happens then there is a bug in our fork
96 implementation somewhere. */
97 system_printf ("%s pass %d failed, %p..%p, done %d, windows pid %u, %E",
98 what, pass, low, high, done, pi.dwProcessId);
106 debug_printf ("done");
110 TerminateProcess (pi.hProcess, 1);
116 resume_child (HANDLE forker_finished)
118 SetEvent (forker_finished);
119 debug_printf ("signalled child");
123 /* Notify parent that it is time for the next step. */
124 static void __stdcall
125 sync_with_parent (const char *s, bool hang_self)
127 debug_printf ("signalling parent: %s", s);
128 fork_info->ready (false);
131 HANDLE h = fork_info->forker_finished;
132 /* Wait for the parent to fill in our stack and heap.
133 Don't wait forever here. If our parent dies we don't want to clog
134 the system. If the wait fails, we really can't continue so exit. */
135 DWORD psync_rc = WaitForSingleObject (h, FORK_WAIT_TIMEOUT);
136 debug_printf ("awake");
140 api_fatal ("WFSO timed out %s", s);
143 if (GetLastError () == ERROR_INVALID_HANDLE &&
144 WaitForSingleObject (fork_info->forker_finished, 1) != WAIT_FAILED)
146 api_fatal ("WFSO failed %s, fork_finished %p, %E", s,
147 fork_info->forker_finished);
150 debug_printf ("no problems");
157 fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
159 extern void fixup_hooks_after_fork ();
160 extern void fixup_timers_after_fork ();
161 extern void __stdcall create_signal_arrived ();
162 debug_printf ("child is running. pid %d, ppid %d, stack here %p",
163 myself->pid, myself->ppid, __builtin_frame_address (0));
165 sync_with_parent ("after longjmp", true);
166 sigproc_printf ("hParent %p, child 1 first_dll %p, load_dlls %d", hParent,
167 first_dll, load_dlls);
169 /* If we've played with the stack, stacksize != 0. That means that
170 fork() was invoked from other than the main thread. Make sure that
171 the threadinfo information is properly set up. */
172 if (fork_info->stacksize)
174 _main_tls = &_my_tls;
175 _main_tls->init_thread (NULL, NULL);
176 _main_tls->local_clib = *_impure_ptr;
177 _impure_ptr = &_main_tls->local_clib;
180 if (wincap.has_security ())
182 set_cygwin_privileges (hProcImpToken);
183 cygheap->user.reimpersonate ();
188 if (GetEnvironmentVariable ("FORKDEBUG", &c, 1))
191 /* This is useful for debugging fork problems. Use gdb to attach to
192 the pid reported here. */
193 if (GetEnvironmentVariable ("CYGWIN_FORK_SLEEP", buf, sizeof (buf)))
195 small_printf ("Sleeping %d after fork, pid %u\n", atoi (buf), GetCurrentProcessId ());
200 set_file_api_mode (current_codepage);
204 if (fixup_mmaps_after_fork (hParent))
205 api_fatal ("recreate_mmaps_after_fork_failed");
207 create_signal_arrived ();
210 /* Incredible but true: If we use sockets and SYSV IPC shared memory,
211 there's a good chance that a duplicated socket in the child occupies
212 memory which is needed to duplicate shared memory from the parent
213 process, if the shared memory hasn't been duplicated already.
214 The same goes very likely for "normal" mmap shared memory, too, but
215 with SYSV IPC it was the first time observed. So, *never* fixup
216 fdtab before fixing up shared memory. */
217 if (fixup_shms_after_fork ())
218 api_fatal ("recreate_shm areas after fork failed");
223 /* If we haven't dynamically loaded any dlls, just signal
224 the parent. Otherwise, load all the dlls, tell the parent
225 that we're done, and wait for the parent to fill in the.
226 loaded dlls' data/bss. */
229 cygheap->fdtab.fixup_after_fork (hParent);
230 sync_with_parent ("performed fork fixup", false);
234 dlls.load_after_fork (hParent, first_dll);
235 cygheap->fdtab.fixup_after_fork (hParent);
236 sync_with_parent ("loaded dlls", true);
239 (void) ForceCloseHandle1 (fork_info->forker_finished, forker_finished);
241 _my_tls.fixup_after_fork ();
244 pthread::atforkchild ();
245 fixup_timers_after_fork ();
246 fixup_hooks_after_fork ();
247 cygbench ("fork-child");
248 cygwin_finished_initializing = true;
252 #ifndef NO_SLOW_PID_REUSE
254 slow_pid_reuse (HANDLE h)
256 static NO_COPY HANDLE last_fork_procs[NPIDS_HELD];
257 static NO_COPY unsigned nfork_procs;
259 if (nfork_procs >= (sizeof (last_fork_procs) / sizeof (last_fork_procs [0])))
261 /* Keep a list of handles to child processes sitting around to prevent
262 Windows from reusing the same pid n times in a row. Having the same pids
263 close in succesion confuses bash. Keeping a handle open will stop
264 windows from reusing the same pid. */
265 if (last_fork_procs[nfork_procs])
266 ForceCloseHandle1 (last_fork_procs[nfork_procs], fork_stupidity);
267 if (DuplicateHandle (hMainProc, h, hMainProc, &last_fork_procs[nfork_procs],
268 0, FALSE, DUPLICATE_SAME_ACCESS))
269 ProtectHandle1 (last_fork_procs[nfork_procs], fork_stupidity);
272 last_fork_procs[nfork_procs] = NULL;
273 system_printf ("couldn't create last_fork_proc, %E");
280 fork_parent (HANDLE&, dll *&first_dll, bool& load_dlls, void *stack_here, child_info_fork &ch)
282 HANDLE forker_finished;
284 PROCESS_INFORMATION pi = {0, NULL, 0, 0};
286 pthread::atforkprepare ();
288 int c_flags = GetPriorityClass (hMainProc) /*|
289 CREATE_NEW_PROCESS_GROUP*/;
290 STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
292 /* If we don't have a console, then don't create a console for the
294 HANDLE console_handle = CreateFile ("CONOUT$", GENERIC_WRITE,
295 FILE_SHARE_WRITE, &sec_none_nih,
296 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
299 if (console_handle != INVALID_HANDLE_VALUE)
300 CloseHandle (console_handle);
302 c_flags |= DETACHED_PROCESS;
304 /* Some file types (currently only sockets) need extra effort in the
305 parent after CreateProcess and before copying the datastructures
306 to the child. So we have to start the child in suspend state,
307 unfortunately, to avoid a race condition. */
308 if (cygheap->fdtab.need_fixup_before ())
309 c_flags |= CREATE_SUSPENDED;
311 /* Remember the address of the first loaded dll and decide
312 if we need to load dlls. We do this here so that this
313 information will be available in the parent and, when
314 the stack is copied, in the child. */
315 first_dll = dlls.start.next;
316 load_dlls = dlls.reload_on_fork && dlls.loaded_dlls;
318 /* This will help some of the confusion. */
321 forker_finished = CreateEvent (&sec_all, FALSE, FALSE, NULL);
322 if (forker_finished == NULL)
324 system_printf ("unable to allocate forker_finished event, %E");
328 ProtectHandleINH (forker_finished);
330 ch.forker_finished = forker_finished;
334 si.cb = sizeof (STARTUPINFO);
335 si.lpReserved2 = (LPBYTE) &ch;
336 si.cbReserved2 = sizeof (ch);
338 /* Remove impersonation */
339 cygheap->user.deimpersonate ();
341 syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
342 myself->progname, myself->progname, c_flags, &si, &pi);
343 bool locked = __malloc_lock ();
344 rc = CreateProcess (myself->progname, /* image to run */
345 myself->progname, /* what we send in arg0 */
348 TRUE, /* inherit handles from parent */
350 NULL, /* environment filled in later */
351 0, /* use current drive/directory */
358 syscall_printf ("CreateProcessA failed, %E");
359 ForceCloseHandle (forker_finished);
360 /* Restore impersonation */
361 cygheap->user.reimpersonate ();
366 /* Fixup the parent datastructure if needed and resume the child's
368 if (cygheap->fdtab.need_fixup_before ())
370 cygheap->fdtab.fixup_before_fork (pi.dwProcessId);
371 ResumeThread (pi.hThread);
374 int child_pid = cygwin_pid (pi.dwProcessId);
375 pinfo child (child_pid, 1);
376 child->start_time = time (NULL); /* Register child's starting time. */
377 child->nice = myself->nice;
381 syscall_printf ("pinfo failed");
382 if (get_errno () != ENOMEM)
387 /* Initialize things that are done later in dll_crt0_1 that aren't done
389 strcpy (child->progname, myself->progname);
391 /* Restore impersonation */
392 cygheap->user.reimpersonate ();
394 ProtectHandle (pi.hThread);
395 /* Protect the handle but name it similarly to the way it will
396 be called in subproc handling. */
397 ProtectHandle1 (pi.hProcess, childhProc);
399 /* Fill in fields in the child's process table entry. */
400 child->dwProcessId = pi.dwProcessId;
401 child.hProcess = pi.hProcess;
403 /* Hopefully, this will succeed. The alternative to doing things this
404 way is to reserve space prior to calling CreateProcess and then fill
405 it in afterwards. This requires more bookkeeping than I like, though,
406 so we'll just do it the easy way. So, terminate any child process if
407 we can't actually record the pid in the internal table. */
408 if (!child.remember (false))
410 TerminateProcess (pi.hProcess, 1);
415 #ifndef NO_SLOW_PID_REUSE
416 slow_pid_reuse (pi.hProcess);
419 /* Wait for subproc to initialize itself. */
420 if (!ch.sync (child, FORK_WAIT_TIMEOUT))
422 system_printf ("child %d died waiting for longjmp before initialization", child_pid);
426 /* CHILD IS STOPPED */
427 debug_printf ("child is alive (but stopped)");
429 /* Initialize, in order: data, bss, heap, stack, dll data, dll bss
430 Note: variables marked as NO_COPY will not be copied
431 since they are placed in a protected segment. */
437 if (&_my_tls == _main_tls)
438 impure_beg = impure_end = NULL;
441 impure_beg = _impure_ptr;
442 impure_end = _impure_ptr + 1;
444 rc = fork_copy (pi, "user/cygwin data",
445 user_data->data_start, user_data->data_end,
446 user_data->bss_start, user_data->bss_end,
447 cygheap->user_heap.base, cygheap->user_heap.ptr,
448 stack_here, ch.stackbottom,
449 dll_data_start, dll_data_end,
450 dll_bss_start, dll_bss_end, impure_beg, impure_end, NULL);
458 /* Now fill data/bss of any DLLs that were linked into the program. */
459 for (dll *d = dlls.istart (DLL_LINK); d; d = dlls.inext ())
461 debug_printf ("copying data/bss of a linked dll");
462 if (!fork_copy (pi, "linked dll data/bss", d->p.data_start, d->p.data_end,
463 d->p.bss_start, d->p.bss_end,
468 /* Start thread, and wait for it to reload dlls. */
469 if (!resume_child (forker_finished))
471 else if (!ch.sync (child, FORK_WAIT_TIMEOUT))
473 system_printf ("child %d died waiting for dll loading", child_pid);
477 /* If DLLs were loaded in the parent, then the child has reloaded all
478 of them and is now waiting to have all of the individual data and
479 bss sections filled in. */
482 /* CHILD IS STOPPED */
483 /* write memory of reloaded dlls */
484 for (dll *d = dlls.istart (DLL_LOAD); d; d = dlls.inext ())
486 debug_printf ("copying data/bss for a loaded dll");
487 if (!fork_copy (pi, "loaded dll data/bss", d->p.data_start, d->p.data_end,
488 d->p.bss_start, d->p.bss_end,
492 /* Start the child up again. */
493 (void) resume_child (forker_finished);
496 ForceCloseHandle (pi.hThread);
497 ForceCloseHandle (forker_finished);
498 forker_finished = NULL;
500 pthread::atforkparent ();
504 /* Common cleanup code for failure cases */
509 /* Remember to de-allocate the fd table. */
511 ForceCloseHandle1 (pi.hProcess, childhProc);
513 ForceCloseHandle (pi.hThread);
515 ForceCloseHandle (forker_finished);
531 debug_printf ("entering");
532 grouped.first_dll = NULL;
533 grouped.load_dlls = 0;
536 __asm__ volatile ("movl %%esp,%0": "=r" (esp));
538 myself->set_has_pgid_children ();
540 if (grouped.ch.parent == NULL)
542 if (grouped.ch.subproc_ready == NULL)
544 system_printf ("unable to allocate subproc_ready event, %E");
548 sig_send (NULL, __SIGHOLD);
549 int res = setjmp (grouped.ch.jmp);
551 res = fork_child (grouped.ch.parent, grouped.first_dll, grouped.load_dlls);
553 res = fork_parent (grouped.ch.parent, grouped.first_dll, grouped.load_dlls, esp, grouped.ch);
554 sig_send (NULL, __SIGNOHOLD);
557 syscall_printf ("%d = fork()", res);
568 /* Dummy function to force second assignment below to actually be
573 return vfork_storage.val ();
581 debug_printf ("stub called");
584 vfork_save *vf = get_vfork_val ();
588 vf = vfork_storage.create ();
592 // FIXME the tls stuff could introduce a signal race if a child process
597 __asm__ volatile ("movl %%esp,%0": "=r" (vf->vfork_esp):);
598 __asm__ volatile ("movl %%ebp,%0": "=r" (vf->vfork_ebp):);
599 for (pp = (char **) vf->frame, esp = vf->vfork_esp;
600 esp <= vf->vfork_ebp + 2; pp++, esp++)
602 vf->ctty = myself->ctty;
603 vf->sid = myself->sid;
604 vf->pgid = myself->pgid;
605 cygheap->ctty_on_hold = cygheap->ctty;
606 vf->open_fhs = cygheap->open_fhs;
607 debug_printf ("cygheap->ctty_on_hold %p, cygheap->open_fhs %d", cygheap->ctty_on_hold, cygheap->open_fhs);
608 int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1;
609 debug_printf ("%d = vfork()", res);
610 _my_tls.call_signal_handler (); // FIXME: racy
615 vf = get_vfork_val ();
617 for (pp = (char **) vf->frame, esp = vf->vfork_esp;
618 esp <= vf->vfork_ebp + 2; pp++, esp++)
621 cygheap->fdtab.vfork_parent_restore ();
623 myself->ctty = vf->ctty;
624 myself->sid = vf->sid;
625 myself->pgid = vf->pgid;
626 termios_printf ("cygheap->ctty %p, cygheap->ctty_on_hold %p", cygheap->ctty, cygheap->ctty_on_hold);
627 cygheap->open_fhs = vf->open_fhs;
631 int exitval = vf->exitval;
633 if ((vf->pid = fork ()) == 0)
639 debug_printf ("exiting vfork, pid %d", pid);
640 sig_dispatch_pending ();
642 _my_tls.call_signal_handler (); // FIXME: racy
649 child_copy (HANDLE h, DWORD pid, const char *what, void *child_start, void *child_end)
651 PROCESS_INFORMATION pi;
653 pi.dwProcessId = pid;
655 debug_printf ("%s, start %p, end %p", what, child_start, child_end);
656 return fork_copy (pi, what, child_start, child_end, NULL);