3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006,
4 2007, 2008, 2009 Red Hat, Inc.
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
23 #include "child_info.h"
27 #include "cygmalloc.h"
31 /* Timeout to wait for child to start, parent to init child, etc. */
32 /* FIXME: Once things stabilize, bump up to a few minutes. */
33 #define FORK_WAIT_TIMEOUT (300 * 1000) /* 300 seconds */
42 int __stdcall parent (volatile char * volatile here);
43 int __stdcall child (volatile char * volatile here);
53 worked = sig_send (NULL, __SIGHOLD) == 0;
66 sig_send (NULL, __SIGNOHOLD);
74 lock_pthread (): bother (1)
76 pthread::atforkprepare ();
85 pthread::atforkparent ();
93 /* Note the order of the locks below. It is important,
94 to avoid races, that the lock order be preserved.
96 pthread is first because it serves as a master lock
97 against other forks being attempted while this one is active.
99 signals is next to stop signal processing for the duration
102 process is last. If it is put before signals, then a deadlock
103 could be introduced if the process attempts to exit due to a signal. */
104 lock_pthread pthread;
105 lock_signals signals;
106 lock_process process;
109 hold_everything (bool& x): ischild (x) {}
110 operator int () const {return signals;}
116 pthread.dont_bother ();
117 process.dont_bother ();
118 signals.dont_bother ();
125 resume_child (HANDLE forker_finished)
127 SetEvent (forker_finished);
128 debug_printf ("signalled child");
132 /* Notify parent that it is time for the next step. */
133 static void __stdcall
134 sync_with_parent (const char *s, bool hang_self)
136 debug_printf ("signalling parent: %s", s);
137 fork_info->ready (false);
140 HANDLE h = fork_info->forker_finished;
141 /* Wait for the parent to fill in our stack and heap.
142 Don't wait forever here. If our parent dies we don't want to clog
143 the system. If the wait fails, we really can't continue so exit. */
144 DWORD psync_rc = WaitForSingleObject (h, FORK_WAIT_TIMEOUT);
145 debug_printf ("awake");
149 api_fatal ("WFSO timed out %s", s);
152 if (GetLastError () == ERROR_INVALID_HANDLE &&
153 WaitForSingleObject (fork_info->forker_finished, 1) != WAIT_FAILED)
155 api_fatal ("WFSO failed %s, fork_finished %p, %E", s,
156 fork_info->forker_finished);
159 debug_printf ("no problems");
166 frok::child (volatile char * volatile here)
168 HANDLE& hParent = ch.parent;
169 extern void fixup_lockf_after_fork ();
170 extern void fixup_hooks_after_fork ();
171 extern void fixup_timers_after_fork ();
172 debug_printf ("child is running. pid %d, ppid %d, stack here %p",
173 myself->pid, myself->ppid, __builtin_frame_address (0));
175 sync_with_parent ("after longjmp", true);
176 sigproc_printf ("hParent %p, load_dlls %d", hParent, load_dlls);
178 /* If we've played with the stack, stacksize != 0. That means that
179 fork() was invoked from other than the main thread. Make sure that
180 the threadinfo information is properly set up. */
181 if (fork_info->stacksize)
183 _main_tls = &_my_tls;
184 _main_tls->init_thread (NULL, NULL);
185 _main_tls->local_clib = *_impure_ptr;
186 _impure_ptr = &_main_tls->local_clib;
189 set_cygwin_privileges (hProcToken);
190 clear_procimptoken ();
191 cygheap->user.reimpersonate ();
194 if (GetEnvironmentVariableA ("FORKDEBUG", NULL, 0))
197 /* This is useful for debugging fork problems. Use gdb to attach to
198 the pid reported here. */
199 if (GetEnvironmentVariableA ("CYGWIN_FORK_SLEEP", buf, sizeof (buf)))
201 small_printf ("Sleeping %d after fork, pid %u\n", atoi (buf), GetCurrentProcessId ());
208 /* Incredible but true: If we use sockets and SYSV IPC shared memory,
209 there's a good chance that a duplicated socket in the child occupies
210 memory which is needed to duplicate shared memory from the parent
211 process, if the shared memory hasn't been duplicated already.
212 The same goes very likely for "normal" mmap shared memory, too, but
213 with SYSV IPC it was the first time observed. So, *never* fixup
214 fdtab before fixing up shared memory. */
215 if (fixup_shms_after_fork ())
216 api_fatal ("recreate_shm areas after fork failed");
220 /* If we haven't dynamically loaded any dlls, just signal
221 the parent. Otherwise, load all the dlls, tell the parent
222 that we're done, and wait for the parent to fill in the.
223 loaded dlls' data/bss. */
226 cygheap->fdtab.fixup_after_fork (hParent);
227 sync_with_parent ("performed fork fixup", false);
231 dlls.load_after_fork (hParent);
232 cygheap->fdtab.fixup_after_fork (hParent);
233 sync_with_parent ("loaded dlls", true);
236 init_console_handler (myself->ctty >= 0);
237 ForceCloseHandle1 (fork_info->forker_finished, forker_finished);
239 pthread::atforkchild ();
240 fixup_timers_after_fork ();
241 cygbench ("fork-child");
243 fixup_hooks_after_fork ();
244 _my_tls.fixup_after_fork ();
245 wait_for_sigthread ();
246 cygwin_finished_initializing = true;
250 #define NO_SLOW_PID_REUSE
251 #ifndef NO_SLOW_PID_REUSE
253 slow_pid_reuse (HANDLE h)
255 static NO_COPY HANDLE last_fork_procs[NPIDS_HELD];
256 static NO_COPY unsigned nfork_procs;
258 if (nfork_procs >= (sizeof (last_fork_procs) / sizeof (last_fork_procs [0])))
260 /* Keep a list of handles to child processes sitting around to prevent
261 Windows from reusing the same pid n times in a row. Having the same pids
262 close in succesion confuses bash. Keeping a handle open will stop
263 windows from reusing the same pid. */
264 if (last_fork_procs[nfork_procs])
265 ForceCloseHandle1 (last_fork_procs[nfork_procs], fork_stupidity);
266 if (DuplicateHandle (GetCurrentProcess (), h,
267 GetCurrentProcess (), &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 frok::parent (volatile char * volatile stack_here)
282 HANDLE forker_finished;
287 bool fix_impersonation = false;
289 static char errbuf[NT_MAX_PATH + 256];
291 int c_flags = GetPriorityClass (GetCurrentProcess ());
292 debug_printf ("priority class %d", c_flags);
294 /* If we don't have a console, then don't create a console for the
296 HANDLE console_handle = CreateFile ("CONOUT$", GENERIC_WRITE,
297 FILE_SHARE_WRITE, &sec_none_nih,
298 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
301 if (console_handle != INVALID_HANDLE_VALUE)
302 CloseHandle (console_handle);
304 c_flags |= DETACHED_PROCESS;
306 /* Some file types (currently only sockets) need extra effort in the
307 parent after CreateProcess and before copying the datastructures
308 to the child. So we have to start the child in suspend state,
309 unfortunately, to avoid a race condition. */
310 if (cygheap->fdtab.need_fixup_before ())
311 c_flags |= CREATE_SUSPENDED;
313 /* Remember if we need to load dynamically linked dlls.
314 We do this here so that this information will be available
315 in the parent and, when the stack is copied, in the child. */
316 load_dlls = dlls.reload_on_fork && dlls.loaded_dlls;
318 forker_finished = CreateEvent (&sec_all, FALSE, FALSE, NULL);
319 if (forker_finished == NULL)
321 this_errno = geterrno_from_win_error ();
322 error = "unable to allocate forker_finished event";
326 ProtectHandleINH (forker_finished);
328 ch.forker_finished = forker_finished;
330 ch.stackbottom = _tlsbase;
331 ch.stacktop = (void *) stack_here;
332 ch.stacksize = (char *) ch.stackbottom - (char *) stack_here;
333 debug_printf ("stack - bottom %p, top %p, size %d",
334 ch.stackbottom, ch.stacktop, ch.stacksize);
336 PROCESS_INFORMATION pi;
339 memset (&si, 0, sizeof (si));
342 si.lpReserved2 = (LPBYTE) &ch;
343 si.cbReserved2 = sizeof (ch);
345 syscall_printf ("CreateProcessW (%W, %W, 0, 0, 1, %p, 0, 0, %p, %p)",
346 myself->progname, myself->progname, c_flags, &si, &pi);
347 bool locked = __malloc_lock ();
348 time_t start_time = time (NULL);
350 /* Remove impersonation */
351 cygheap->user.deimpersonate ();
352 fix_impersonation = true;
356 rc = CreateProcessW (myself->progname, /* image to run */
357 myself->progname, /* what we send in arg0 */
360 TRUE, /* inherit handles from parent */
362 NULL, /* environment filled in later */
363 0, /* use current drive/directory */
369 this_errno = geterrno_from_win_error ();
370 __small_sprintf (errbuf, "CreateProcessW failed for '%W'", myself->progname);
372 memset (&pi, 0, sizeof (pi));
376 if (cygheap->fdtab.need_fixup_before ())
378 cygheap->fdtab.fixup_before_fork (pi.dwProcessId);
379 ResumeThread (pi.hThread);
382 CloseHandle (pi.hThread);
384 /* Protect the handle but name it similarly to the way it will
385 be called in subproc handling. */
386 ProtectHandle1 (pi.hProcess, childhProc);
388 strace.write_childpid (ch, pi.dwProcessId);
390 /* Wait for subproc to initialize itself. */
391 if (!ch.sync (pi.dwProcessId, pi.hProcess, FORK_WAIT_TIMEOUT))
393 DWORD exit_code = ch.proc_retry (pi.hProcess);
397 /* Not thread safe, but do we care? */
398 __small_sprintf (errbuf, "died waiting for longjmp before initialization, "
399 "retry %d, exit code %p", ch.retry, exit_code);
406 /* Restore impersonation */
407 cygheap->user.reimpersonate ();
408 fix_impersonation = false;
410 child_pid = cygwin_pid (pi.dwProcessId);
411 child.init (child_pid, 1, NULL);
415 this_errno = get_errno () == ENOMEM ? ENOMEM : EAGAIN;
417 error = "pinfo failed";
419 syscall_printf ("pinfo failed");
424 child->start_time = start_time; /* Register child's starting time. */
425 child->nice = myself->nice;
427 /* Initialize things that are done later in dll_crt0_1 that aren't done
429 wcscpy (child->progname, myself->progname);
431 /* Fill in fields in the child's process table entry. */
432 child->dwProcessId = pi.dwProcessId;
433 child.hProcess = pi.hProcess;
435 /* Hopefully, this will succeed. The alternative to doing things this
436 way is to reserve space prior to calling CreateProcess and then fill
437 it in afterwards. This requires more bookkeeping than I like, though,
438 so we'll just do it the easy way. So, terminate any child process if
439 we can't actually record the pid in the internal table. */
440 if (!child.remember (false))
442 TerminateProcess (pi.hProcess, 1);
445 error = "child.remember failed";
450 #ifndef NO_SLOW_PID_REUSE
451 slow_pid_reuse (pi.hProcess);
454 /* CHILD IS STOPPED */
455 debug_printf ("child is alive (but stopped)");
457 /* Initialize, in order: stack, dll data, dll bss.
458 data, bss, heap were done earlier (in dcrt0.cc)
459 Note: variables marked as NO_COPY will not be copied since they are
460 placed in a protected segment. */
463 const void *impure_beg;
464 const void *impure_end;
466 if (&_my_tls == _main_tls)
467 impure_beg = impure_end = impure = NULL;
471 impure_beg = _impure_ptr;
472 impure_end = _impure_ptr + 1;
474 rc = child_copy (pi.hProcess, true,
475 "stack", stack_here, ch.stackbottom,
476 impure, impure_beg, impure_end,
484 this_errno = get_errno ();
486 if (!GetExitCodeProcess (pi.hProcess, &exit_code))
487 exit_code = 0xdeadbeef;
488 __small_sprintf (errbuf, "pid %u, exitval %p", pi.dwProcessId, exit_code);
493 /* Now fill data/bss of any DLLs that were linked into the program. */
494 for (dll *d = dlls.istart (DLL_LINK); d; d = dlls.inext ())
496 debug_printf ("copying data/bss of a linked dll");
497 if (!child_copy (pi.hProcess, true,
498 "linked dll data", d->p.data_start, d->p.data_end,
499 "linked dll bss", d->p.bss_start, d->p.bss_end,
502 this_errno = get_errno ();
505 if (!GetExitCodeProcess (pi.hProcess, &exit_code))
506 exit_code = 0xdeadbeef;
507 __small_sprintf (errbuf, "pid %u, exitval %p", pi.dwProcessId, exit_code);
514 /* Start thread, and then wait for it to reload dlls. */
515 resume_child (forker_finished);
516 if (!ch.sync (child->pid, pi.hProcess, FORK_WAIT_TIMEOUT))
519 error = "died waiting for dll loading";
523 /* If DLLs were loaded in the parent, then the child has reloaded all
524 of them and is now waiting to have all of the individual data and
525 bss sections filled in. */
528 /* CHILD IS STOPPED */
529 /* write memory of reloaded dlls */
530 for (dll *d = dlls.istart (DLL_LOAD); d; d = dlls.inext ())
532 debug_printf ("copying data/bss for a loaded dll");
533 if (!child_copy (pi.hProcess, true,
534 "loaded dll data", d->p.data_start, d->p.data_end,
535 "loaded dll bss", d->p.bss_start, d->p.bss_end,
538 this_errno = get_errno ();
540 error = "copying data/bss for a loaded dll";
545 /* Start the child up again. */
546 resume_child (forker_finished);
549 ForceCloseHandle (forker_finished);
550 forker_finished = NULL;
554 /* Common cleanup code for failure cases */
556 if (fix_impersonation)
557 cygheap->user.reimpersonate ();
561 /* Remember to de-allocate the fd table. */
562 if (pi.hProcess && !child.hProcess)
563 ForceCloseHandle1 (pi.hProcess, childhProc);
565 ForceCloseHandle (forker_finished);
566 debug_printf ("returning -1");
575 debug_printf ("entering");
576 grouped.load_dlls = 0;
579 bool ischild = false;
581 myself->set_has_pgid_children ();
583 if (grouped.ch.parent == NULL)
585 if (grouped.ch.subproc_ready == NULL)
587 system_printf ("unable to allocate subproc_ready event, %E");
592 hold_everything held_everything (ischild);
593 /* This tmp_pathbuf constructor is required here because the below setjmp
594 magic will otherwise not restore the original buffer count values in
595 the thread-local storage. A process forking too deeply will run into
596 the problem to be out of temporary TLS path buffers. */
599 if (!held_everything)
607 ischild = !!setjmp (grouped.ch.jmp);
609 volatile char * volatile esp;
610 __asm__ volatile ("movl %%esp,%0": "=r" (esp));
613 res = grouped.parent (esp);
616 res = grouped.child (esp);
617 ischild = true; /* might have been reset by fork mem copy */
622 if (ischild || res > 0)
623 /* everything is ok */;
627 syscall_printf ("fork failed - child pid %d, errno %d", grouped.child_pid, grouped.this_errno);
630 char buf[strlen (grouped.error) + sizeof ("child %d - , errno 4294967295 ")];
631 strcpy (buf, "child %d - ");
632 strcat (buf, grouped.error);
633 strcat (buf, ", errno %d");
634 system_printf (buf, grouped.child_pid, grouped.this_errno);
637 set_errno (grouped.this_errno);
639 syscall_printf ("%d = fork()", res);
650 /* Dummy function to force second assignment below to actually be
655 return vfork_storage.val ();
663 debug_printf ("stub called");
666 vfork_save *vf = get_vfork_val ();
670 vf = vfork_storage.create ();
674 // FIXME the tls stuff could introduce a signal race if a child process
679 __asm__ volatile ("movl %%esp,%0": "=r" (vf->vfork_esp):);
680 __asm__ volatile ("movl %%ebp,%0": "=r" (vf->vfork_ebp):);
681 for (pp = (char **) vf->frame, esp = vf->vfork_esp;
682 esp <= vf->vfork_ebp + 2; pp++, esp++)
684 vf->ctty = myself->ctty;
685 vf->sid = myself->sid;
686 vf->pgid = myself->pgid;
687 cygheap->ctty_on_hold = cygheap->ctty;
688 vf->console_count = cygheap->console_count;
689 debug_printf ("cygheap->ctty_on_hold %p, cygheap->console_count %d", cygheap->ctty_on_hold, cygheap->console_count);
690 int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1;
691 debug_printf ("%d = vfork()", res);
692 _my_tls.call_signal_handler (); // FIXME: racy
697 vf = get_vfork_val ();
699 for (pp = (char **) vf->frame, esp = vf->vfork_esp;
700 esp <= vf->vfork_ebp + 2; pp++, esp++)
703 cygheap->fdtab.vfork_parent_restore ();
705 myself->ctty = vf->ctty;
706 myself->sid = vf->sid;
707 myself->pgid = vf->pgid;
708 termios_printf ("cygheap->ctty %p, cygheap->ctty_on_hold %p", cygheap->ctty, cygheap->ctty_on_hold);
709 cygheap->console_count = vf->console_count;
713 int exitval = vf->exitval;
715 if ((vf->pid = fork ()) == 0)
721 debug_printf ("exiting vfork, pid %d", pid);
722 sig_dispatch_pending ();
724 _my_tls.call_signal_handler (); // FIXME: racy
730 /* Copy memory from one process to another. */
733 child_copy (HANDLE hp, bool write, ...)
736 va_start (args, write);
737 static const char *huh[] = {"read", "write"};
740 while ((what = va_arg (args, char *)))
742 char *low = va_arg (args, char *);
743 char *high = va_arg (args, char *);
744 DWORD todo = wincap.chunksize () ?: high - low;
747 for (here = low; here < high; here += todo)
750 if (here + todo > high)
754 res = WriteProcessMemory (hp, here, here, todo, &done);
756 res = ReadProcessMemory (hp, here, here, todo, &done);
757 debug_printf ("%s - hp %p low %p, high %p, res %d", what, hp, low, high, res);
758 if (!res || todo != done)
762 /* If this happens then there is a bug in our fork
763 implementation somewhere. */
764 system_printf ("%s %s copy failed, %p..%p, done %d, windows pid %u, %E",
765 what, huh[write], low, high, done, myself->dwProcessId);
772 debug_printf ("done");
777 TerminateProcess (hp, 1);