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 /* FIXME: myself->progname should be converted to WCHAR. */
347 PWCHAR progname = tp.w_get ();
348 sys_mbstowcs (progname, NT_MAX_PATH, myself->progname);
350 syscall_printf ("CreateProcess (%W, %W, 0, 0, 1, %p, 0, 0, %p, %p)",
351 progname, progname, c_flags, &si, &pi);
352 bool locked = __malloc_lock ();
353 time_t start_time = time (NULL);
355 /* Remove impersonation */
356 cygheap->user.deimpersonate ();
357 fix_impersonation = true;
361 rc = CreateProcessW (progname, /* image to run */
362 progname, /* what we send in arg0 */
365 TRUE, /* inherit handles from parent */
367 NULL, /* environment filled in later */
368 0, /* use current drive/directory */
374 this_errno = geterrno_from_win_error ();
375 error = "CreateProcessW failed";
376 memset (&pi, 0, sizeof (pi));
380 if (cygheap->fdtab.need_fixup_before ())
382 cygheap->fdtab.fixup_before_fork (pi.dwProcessId);
383 ResumeThread (pi.hThread);
386 CloseHandle (pi.hThread);
388 /* Protect the handle but name it similarly to the way it will
389 be called in subproc handling. */
390 ProtectHandle1 (pi.hProcess, childhProc);
392 strace.write_childpid (ch, pi.dwProcessId);
394 /* Wait for subproc to initialize itself. */
395 if (!ch.sync (pi.dwProcessId, pi.hProcess, FORK_WAIT_TIMEOUT))
397 DWORD exit_code = ch.proc_retry (pi.hProcess);
401 /* Not thread safe, but do we care? */
402 __small_sprintf (errbuf, "died waiting for longjmp before initialization, "
403 "retry %d, exit code %p", ch.retry, exit_code);
410 /* Restore impersonation */
411 cygheap->user.reimpersonate ();
412 fix_impersonation = false;
414 child_pid = cygwin_pid (pi.dwProcessId);
415 child.init (child_pid, 1, NULL);
419 this_errno = get_errno () == ENOMEM ? ENOMEM : EAGAIN;
421 error = "pinfo failed";
423 syscall_printf ("pinfo failed");
428 child->start_time = start_time; /* Register child's starting time. */
429 child->nice = myself->nice;
431 /* Initialize things that are done later in dll_crt0_1 that aren't done
433 strcpy (child->progname, myself->progname);
435 /* Fill in fields in the child's process table entry. */
436 child->dwProcessId = pi.dwProcessId;
437 child.hProcess = pi.hProcess;
439 /* Hopefully, this will succeed. The alternative to doing things this
440 way is to reserve space prior to calling CreateProcess and then fill
441 it in afterwards. This requires more bookkeeping than I like, though,
442 so we'll just do it the easy way. So, terminate any child process if
443 we can't actually record the pid in the internal table. */
444 if (!child.remember (false))
446 TerminateProcess (pi.hProcess, 1);
449 error = "child.remember failed";
454 #ifndef NO_SLOW_PID_REUSE
455 slow_pid_reuse (pi.hProcess);
458 /* CHILD IS STOPPED */
459 debug_printf ("child is alive (but stopped)");
461 /* Initialize, in order: stack, dll data, dll bss.
462 data, bss, heap were done earlier (in dcrt0.cc)
463 Note: variables marked as NO_COPY will not be copied since they are
464 placed in a protected segment. */
467 const void *impure_beg;
468 const void *impure_end;
470 if (&_my_tls == _main_tls)
471 impure_beg = impure_end = impure = NULL;
475 impure_beg = _impure_ptr;
476 impure_end = _impure_ptr + 1;
478 rc = child_copy (pi.hProcess, true,
479 "stack", stack_here, ch.stackbottom,
480 impure, impure_beg, impure_end,
488 this_errno = get_errno ();
490 if (!GetExitCodeProcess (pi.hProcess, &exit_code))
491 exit_code = 0xdeadbeef;
492 __small_sprintf (errbuf, "pid %u, exitval %p", pi.dwProcessId, exit_code);
497 /* Now fill data/bss of any DLLs that were linked into the program. */
498 for (dll *d = dlls.istart (DLL_LINK); d; d = dlls.inext ())
500 debug_printf ("copying data/bss of a linked dll");
501 if (!child_copy (pi.hProcess, true,
502 "linked dll data", d->p.data_start, d->p.data_end,
503 "linked dll bss", d->p.bss_start, d->p.bss_end,
506 this_errno = get_errno ();
509 if (!GetExitCodeProcess (pi.hProcess, &exit_code))
510 exit_code = 0xdeadbeef;
511 __small_sprintf (errbuf, "pid %u, exitval %p", pi.dwProcessId, exit_code);
518 /* Start thread, and then wait for it to reload dlls. */
519 resume_child (forker_finished);
520 if (!ch.sync (child->pid, pi.hProcess, FORK_WAIT_TIMEOUT))
523 error = "died waiting for dll loading";
527 /* If DLLs were loaded in the parent, then the child has reloaded all
528 of them and is now waiting to have all of the individual data and
529 bss sections filled in. */
532 /* CHILD IS STOPPED */
533 /* write memory of reloaded dlls */
534 for (dll *d = dlls.istart (DLL_LOAD); d; d = dlls.inext ())
536 debug_printf ("copying data/bss for a loaded dll");
537 if (!child_copy (pi.hProcess, true,
538 "loaded dll data", d->p.data_start, d->p.data_end,
539 "loaded dll bss", d->p.bss_start, d->p.bss_end,
542 this_errno = get_errno ();
544 error = "copying data/bss for a loaded dll";
549 /* Start the child up again. */
550 resume_child (forker_finished);
553 ForceCloseHandle (forker_finished);
554 forker_finished = NULL;
558 /* Common cleanup code for failure cases */
560 if (fix_impersonation)
561 cygheap->user.reimpersonate ();
565 /* Remember to de-allocate the fd table. */
566 if (pi.hProcess && !child.hProcess)
567 ForceCloseHandle1 (pi.hProcess, childhProc);
569 ForceCloseHandle (forker_finished);
570 debug_printf ("returning -1");
579 debug_printf ("entering");
580 grouped.load_dlls = 0;
583 bool ischild = false;
585 myself->set_has_pgid_children ();
587 if (grouped.ch.parent == NULL)
589 if (grouped.ch.subproc_ready == NULL)
591 system_printf ("unable to allocate subproc_ready event, %E");
596 hold_everything held_everything (ischild);
597 /* This tmp_pathbuf constructor is required here because the below setjmp
598 magic will otherwise not restore the original buffer count values in
599 the thread-local storage. A process forking too deeply will run into
600 the problem to be out of temporary TLS path buffers. */
603 if (!held_everything)
611 ischild = !!setjmp (grouped.ch.jmp);
613 volatile char * volatile esp;
614 __asm__ volatile ("movl %%esp,%0": "=r" (esp));
617 res = grouped.parent (esp);
620 res = grouped.child (esp);
621 ischild = true; /* might have been reset by fork mem copy */
626 if (ischild || res > 0)
627 /* everything is ok */;
631 syscall_printf ("fork failed - child pid %d, errno %d", grouped.child_pid, grouped.this_errno);
634 char buf[strlen (grouped.error) + sizeof ("child %d - , errno 4294967295 ")];
635 strcpy (buf, "child %d - ");
636 strcat (buf, grouped.error);
637 strcat (buf, ", errno %d");
638 system_printf (buf, grouped.child_pid, grouped.this_errno);
641 set_errno (grouped.this_errno);
643 syscall_printf ("%d = fork()", res);
654 /* Dummy function to force second assignment below to actually be
659 return vfork_storage.val ();
667 debug_printf ("stub called");
670 vfork_save *vf = get_vfork_val ();
674 vf = vfork_storage.create ();
678 // FIXME the tls stuff could introduce a signal race if a child process
683 __asm__ volatile ("movl %%esp,%0": "=r" (vf->vfork_esp):);
684 __asm__ volatile ("movl %%ebp,%0": "=r" (vf->vfork_ebp):);
685 for (pp = (char **) vf->frame, esp = vf->vfork_esp;
686 esp <= vf->vfork_ebp + 2; pp++, esp++)
688 vf->ctty = myself->ctty;
689 vf->sid = myself->sid;
690 vf->pgid = myself->pgid;
691 cygheap->ctty_on_hold = cygheap->ctty;
692 vf->console_count = cygheap->console_count;
693 debug_printf ("cygheap->ctty_on_hold %p, cygheap->console_count %d", cygheap->ctty_on_hold, cygheap->console_count);
694 int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1;
695 debug_printf ("%d = vfork()", res);
696 _my_tls.call_signal_handler (); // FIXME: racy
701 vf = get_vfork_val ();
703 for (pp = (char **) vf->frame, esp = vf->vfork_esp;
704 esp <= vf->vfork_ebp + 2; pp++, esp++)
707 cygheap->fdtab.vfork_parent_restore ();
709 myself->ctty = vf->ctty;
710 myself->sid = vf->sid;
711 myself->pgid = vf->pgid;
712 termios_printf ("cygheap->ctty %p, cygheap->ctty_on_hold %p", cygheap->ctty, cygheap->ctty_on_hold);
713 cygheap->console_count = vf->console_count;
717 int exitval = vf->exitval;
719 if ((vf->pid = fork ()) == 0)
725 debug_printf ("exiting vfork, pid %d", pid);
726 sig_dispatch_pending ();
728 _my_tls.call_signal_handler (); // FIXME: racy
734 /* Copy memory from one process to another. */
737 child_copy (HANDLE hp, bool write, ...)
740 va_start (args, write);
741 static const char *huh[] = {"read", "write"};
744 while ((what = va_arg (args, char *)))
746 char *low = va_arg (args, char *);
747 char *high = va_arg (args, char *);
748 DWORD todo = wincap.chunksize () ?: high - low;
751 for (here = low; here < high; here += todo)
754 if (here + todo > high)
758 res = WriteProcessMemory (hp, here, here, todo, &done);
760 res = ReadProcessMemory (hp, here, here, todo, &done);
761 debug_printf ("%s - hp %p low %p, high %p, res %d", what, hp, low, high, res);
762 if (!res || todo != done)
766 /* If this happens then there is a bug in our fork
767 implementation somewhere. */
768 system_printf ("%s %s copy failed, %p..%p, done %d, windows pid %u, %E",
769 what, huh[write], low, high, done, myself->dwProcessId);
776 debug_printf ("done");
781 TerminateProcess (hp, 1);