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[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 ("CreateProcess (%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 error = "CreateProcessW failed";
371 memset (&pi, 0, sizeof (pi));
375 if (cygheap->fdtab.need_fixup_before ())
377 cygheap->fdtab.fixup_before_fork (pi.dwProcessId);
378 ResumeThread (pi.hThread);
381 CloseHandle (pi.hThread);
383 /* Protect the handle but name it similarly to the way it will
384 be called in subproc handling. */
385 ProtectHandle1 (pi.hProcess, childhProc);
387 strace.write_childpid (ch, pi.dwProcessId);
389 /* Wait for subproc to initialize itself. */
390 if (!ch.sync (pi.dwProcessId, pi.hProcess, FORK_WAIT_TIMEOUT))
392 DWORD exit_code = ch.proc_retry (pi.hProcess);
396 /* Not thread safe, but do we care? */
397 __small_sprintf (errbuf, "died waiting for longjmp before initialization, "
398 "retry %d, exit code %p", ch.retry, exit_code);
405 /* Restore impersonation */
406 cygheap->user.reimpersonate ();
407 fix_impersonation = false;
409 child_pid = cygwin_pid (pi.dwProcessId);
410 child.init (child_pid, 1, NULL);
414 this_errno = get_errno () == ENOMEM ? ENOMEM : EAGAIN;
416 error = "pinfo failed";
418 syscall_printf ("pinfo failed");
423 child->start_time = start_time; /* Register child's starting time. */
424 child->nice = myself->nice;
426 /* Initialize things that are done later in dll_crt0_1 that aren't done
428 wcscpy (child->progname, myself->progname);
430 /* Fill in fields in the child's process table entry. */
431 child->dwProcessId = pi.dwProcessId;
432 child.hProcess = pi.hProcess;
434 /* Hopefully, this will succeed. The alternative to doing things this
435 way is to reserve space prior to calling CreateProcess and then fill
436 it in afterwards. This requires more bookkeeping than I like, though,
437 so we'll just do it the easy way. So, terminate any child process if
438 we can't actually record the pid in the internal table. */
439 if (!child.remember (false))
441 TerminateProcess (pi.hProcess, 1);
444 error = "child.remember failed";
449 #ifndef NO_SLOW_PID_REUSE
450 slow_pid_reuse (pi.hProcess);
453 /* CHILD IS STOPPED */
454 debug_printf ("child is alive (but stopped)");
456 /* Initialize, in order: stack, dll data, dll bss.
457 data, bss, heap were done earlier (in dcrt0.cc)
458 Note: variables marked as NO_COPY will not be copied since they are
459 placed in a protected segment. */
462 const void *impure_beg;
463 const void *impure_end;
465 if (&_my_tls == _main_tls)
466 impure_beg = impure_end = impure = NULL;
470 impure_beg = _impure_ptr;
471 impure_end = _impure_ptr + 1;
473 rc = child_copy (pi.hProcess, true,
474 "stack", stack_here, ch.stackbottom,
475 impure, impure_beg, impure_end,
483 this_errno = get_errno ();
485 if (!GetExitCodeProcess (pi.hProcess, &exit_code))
486 exit_code = 0xdeadbeef;
487 __small_sprintf (errbuf, "pid %u, exitval %p", pi.dwProcessId, exit_code);
492 /* Now fill data/bss of any DLLs that were linked into the program. */
493 for (dll *d = dlls.istart (DLL_LINK); d; d = dlls.inext ())
495 debug_printf ("copying data/bss of a linked dll");
496 if (!child_copy (pi.hProcess, true,
497 "linked dll data", d->p.data_start, d->p.data_end,
498 "linked dll bss", d->p.bss_start, d->p.bss_end,
501 this_errno = get_errno ();
504 if (!GetExitCodeProcess (pi.hProcess, &exit_code))
505 exit_code = 0xdeadbeef;
506 __small_sprintf (errbuf, "pid %u, exitval %p", pi.dwProcessId, exit_code);
513 /* Start thread, and then wait for it to reload dlls. */
514 resume_child (forker_finished);
515 if (!ch.sync (child->pid, pi.hProcess, FORK_WAIT_TIMEOUT))
518 error = "died waiting for dll loading";
522 /* If DLLs were loaded in the parent, then the child has reloaded all
523 of them and is now waiting to have all of the individual data and
524 bss sections filled in. */
527 /* CHILD IS STOPPED */
528 /* write memory of reloaded dlls */
529 for (dll *d = dlls.istart (DLL_LOAD); d; d = dlls.inext ())
531 debug_printf ("copying data/bss for a loaded dll");
532 if (!child_copy (pi.hProcess, true,
533 "loaded dll data", d->p.data_start, d->p.data_end,
534 "loaded dll bss", d->p.bss_start, d->p.bss_end,
537 this_errno = get_errno ();
539 error = "copying data/bss for a loaded dll";
544 /* Start the child up again. */
545 resume_child (forker_finished);
548 ForceCloseHandle (forker_finished);
549 forker_finished = NULL;
553 /* Common cleanup code for failure cases */
555 if (fix_impersonation)
556 cygheap->user.reimpersonate ();
560 /* Remember to de-allocate the fd table. */
561 if (pi.hProcess && !child.hProcess)
562 ForceCloseHandle1 (pi.hProcess, childhProc);
564 ForceCloseHandle (forker_finished);
565 debug_printf ("returning -1");
574 debug_printf ("entering");
575 grouped.load_dlls = 0;
578 bool ischild = false;
580 myself->set_has_pgid_children ();
582 if (grouped.ch.parent == NULL)
584 if (grouped.ch.subproc_ready == NULL)
586 system_printf ("unable to allocate subproc_ready event, %E");
591 hold_everything held_everything (ischild);
592 /* This tmp_pathbuf constructor is required here because the below setjmp
593 magic will otherwise not restore the original buffer count values in
594 the thread-local storage. A process forking too deeply will run into
595 the problem to be out of temporary TLS path buffers. */
598 if (!held_everything)
606 ischild = !!setjmp (grouped.ch.jmp);
608 volatile char * volatile esp;
609 __asm__ volatile ("movl %%esp,%0": "=r" (esp));
612 res = grouped.parent (esp);
615 res = grouped.child (esp);
616 ischild = true; /* might have been reset by fork mem copy */
621 if (ischild || res > 0)
622 /* everything is ok */;
626 syscall_printf ("fork failed - child pid %d, errno %d", grouped.child_pid, grouped.this_errno);
629 char buf[strlen (grouped.error) + sizeof ("child %d - , errno 4294967295 ")];
630 strcpy (buf, "child %d - ");
631 strcat (buf, grouped.error);
632 strcat (buf, ", errno %d");
633 system_printf (buf, grouped.child_pid, grouped.this_errno);
636 set_errno (grouped.this_errno);
638 syscall_printf ("%d = fork()", res);
649 /* Dummy function to force second assignment below to actually be
654 return vfork_storage.val ();
662 debug_printf ("stub called");
665 vfork_save *vf = get_vfork_val ();
669 vf = vfork_storage.create ();
673 // FIXME the tls stuff could introduce a signal race if a child process
678 __asm__ volatile ("movl %%esp,%0": "=r" (vf->vfork_esp):);
679 __asm__ volatile ("movl %%ebp,%0": "=r" (vf->vfork_ebp):);
680 for (pp = (char **) vf->frame, esp = vf->vfork_esp;
681 esp <= vf->vfork_ebp + 2; pp++, esp++)
683 vf->ctty = myself->ctty;
684 vf->sid = myself->sid;
685 vf->pgid = myself->pgid;
686 cygheap->ctty_on_hold = cygheap->ctty;
687 vf->console_count = cygheap->console_count;
688 debug_printf ("cygheap->ctty_on_hold %p, cygheap->console_count %d", cygheap->ctty_on_hold, cygheap->console_count);
689 int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1;
690 debug_printf ("%d = vfork()", res);
691 _my_tls.call_signal_handler (); // FIXME: racy
696 vf = get_vfork_val ();
698 for (pp = (char **) vf->frame, esp = vf->vfork_esp;
699 esp <= vf->vfork_ebp + 2; pp++, esp++)
702 cygheap->fdtab.vfork_parent_restore ();
704 myself->ctty = vf->ctty;
705 myself->sid = vf->sid;
706 myself->pgid = vf->pgid;
707 termios_printf ("cygheap->ctty %p, cygheap->ctty_on_hold %p", cygheap->ctty, cygheap->ctty_on_hold);
708 cygheap->console_count = vf->console_count;
712 int exitval = vf->exitval;
714 if ((vf->pid = fork ()) == 0)
720 debug_printf ("exiting vfork, pid %d", pid);
721 sig_dispatch_pending ();
723 _my_tls.call_signal_handler (); // FIXME: racy
729 /* Copy memory from one process to another. */
732 child_copy (HANDLE hp, bool write, ...)
735 va_start (args, write);
736 static const char *huh[] = {"read", "write"};
739 while ((what = va_arg (args, char *)))
741 char *low = va_arg (args, char *);
742 char *high = va_arg (args, char *);
743 DWORD todo = wincap.chunksize () ?: high - low;
746 for (here = low; here < high; here += todo)
749 if (here + todo > high)
753 res = WriteProcessMemory (hp, here, here, todo, &done);
755 res = ReadProcessMemory (hp, here, here, todo, &done);
756 debug_printf ("%s - hp %p low %p, high %p, res %d", what, hp, low, high, res);
757 if (!res || todo != done)
761 /* If this happens then there is a bug in our fork
762 implementation somewhere. */
763 system_printf ("%s %s copy failed, %p..%p, done %d, windows pid %u, %E",
764 what, huh[write], low, high, done, myself->dwProcessId);
771 debug_printf ("done");
776 TerminateProcess (hp, 1);