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__
53 int __stdcall parent (void *esp);
54 int __stdcall child (void *esp);
59 stack_base (child_info_fork *ch)
61 ch->stackbottom = _tlsbase;
63 ch->stacksize = (char *) ch->stackbottom - (char *) &ch;
64 debug_printf ("bottom %p, top %p, stack %p, size %d, reserve %d",
65 ch->stackbottom, ch->stacktop, &ch, ch->stacksize,
66 (char *) ch->stackbottom - (char *) ch->stacktop);
69 /* Copy memory from parent to child.
70 The result is a boolean indicating success. */
73 fork_copy (PROCESS_INFORMATION& pi, const char *what, ...)
79 va_start (args, what);
81 while ((low = va_arg (args, char *)))
83 char *high = va_arg (args, char *);
84 DWORD todo = wincap.chunksize () ?: high - low;
87 for (here = low; here < high; here += todo)
90 if (here + todo > high)
94 res = WriteProcessMemory (pi.hProcess, here, here, todo, &done);
96 res = ReadProcessMemory (pi.hProcess, here, here, todo, &done);
97 debug_printf ("child handle %p, low %p, high %p, res %d", pi.hProcess,
99 if (!res || todo != done)
103 /* If this happens then there is a bug in our fork
104 implementation somewhere. */
105 system_printf ("%s pass %d failed, %p..%p, done %d, windows pid %u, %E",
106 what, pass, low, high, done, pi.dwProcessId);
114 debug_printf ("done");
118 TerminateProcess (pi.hProcess, 1);
124 resume_child (HANDLE forker_finished)
126 SetEvent (forker_finished);
127 debug_printf ("signalled child");
131 /* Notify parent that it is time for the next step. */
132 static void __stdcall
133 sync_with_parent (const char *s, bool hang_self)
135 debug_printf ("signalling parent: %s", s);
136 fork_info->ready (false);
139 HANDLE h = fork_info->forker_finished;
140 /* Wait for the parent to fill in our stack and heap.
141 Don't wait forever here. If our parent dies we don't want to clog
142 the system. If the wait fails, we really can't continue so exit. */
143 DWORD psync_rc = WaitForSingleObject (h, FORK_WAIT_TIMEOUT);
144 debug_printf ("awake");
148 api_fatal ("WFSO timed out %s", s);
151 if (GetLastError () == ERROR_INVALID_HANDLE &&
152 WaitForSingleObject (fork_info->forker_finished, 1) != WAIT_FAILED)
154 api_fatal ("WFSO failed %s, fork_finished %p, %E", s,
155 fork_info->forker_finished);
158 debug_printf ("no problems");
167 HANDLE& hParent = ch.parent;
168 extern void fixup_hooks_after_fork ();
169 extern void fixup_timers_after_fork ();
170 debug_printf ("child is running. pid %d, ppid %d, stack here %p",
171 myself->pid, myself->ppid, __builtin_frame_address (0));
173 sync_with_parent ("after longjmp", true);
174 sigproc_printf ("hParent %p, child 1 first_dll %p, load_dlls %d", hParent,
175 first_dll, load_dlls);
177 /* If we've played with the stack, stacksize != 0. That means that
178 fork() was invoked from other than the main thread. Make sure that
179 the threadinfo information is properly set up. */
180 if (fork_info->stacksize)
182 _main_tls = &_my_tls;
183 _main_tls->init_thread (NULL, NULL);
184 _main_tls->local_clib = *_impure_ptr;
185 _impure_ptr = &_main_tls->local_clib;
188 if (wincap.has_security ())
190 set_cygwin_privileges (hProcImpToken);
191 cygheap->user.reimpersonate ();
196 if (GetEnvironmentVariable ("FORKDEBUG", &c, 1))
199 /* This is useful for debugging fork problems. Use gdb to attach to
200 the pid reported here. */
201 if (GetEnvironmentVariable ("CYGWIN_FORK_SLEEP", buf, sizeof (buf)))
203 small_printf ("Sleeping %d after fork, pid %u\n", atoi (buf), GetCurrentProcessId ());
208 set_file_api_mode (current_codepage);
212 if (fixup_mmaps_after_fork (hParent))
213 api_fatal ("recreate_mmaps_after_fork_failed");
216 /* Incredible but true: If we use sockets and SYSV IPC shared memory,
217 there's a good chance that a duplicated socket in the child occupies
218 memory which is needed to duplicate shared memory from the parent
219 process, if the shared memory hasn't been duplicated already.
220 The same goes very likely for "normal" mmap shared memory, too, but
221 with SYSV IPC it was the first time observed. So, *never* fixup
222 fdtab before fixing up shared memory. */
223 if (fixup_shms_after_fork ())
224 api_fatal ("recreate_shm areas after fork failed");
229 /* If we haven't dynamically loaded any dlls, just signal
230 the parent. Otherwise, load all the dlls, tell the parent
231 that we're done, and wait for the parent to fill in the.
232 loaded dlls' data/bss. */
235 cygheap->fdtab.fixup_after_fork (hParent);
236 sync_with_parent ("performed fork fixup", false);
240 dlls.load_after_fork (hParent, first_dll);
241 cygheap->fdtab.fixup_after_fork (hParent);
242 sync_with_parent ("loaded dlls", true);
245 ForceCloseHandle1 (fork_info->forker_finished, forker_finished);
247 _my_tls.fixup_after_fork ();
250 pthread::atforkchild ();
251 fixup_timers_after_fork ();
252 fixup_hooks_after_fork ();
253 cygbench ("fork-child");
255 cygwin_finished_initializing = true;
259 #define NO_SLOW_PID_REUSE
260 #ifndef NO_SLOW_PID_REUSE
262 slow_pid_reuse (HANDLE h)
264 static NO_COPY HANDLE last_fork_procs[NPIDS_HELD];
265 static NO_COPY unsigned nfork_procs;
267 if (nfork_procs >= (sizeof (last_fork_procs) / sizeof (last_fork_procs [0])))
269 /* Keep a list of handles to child processes sitting around to prevent
270 Windows from reusing the same pid n times in a row. Having the same pids
271 close in succesion confuses bash. Keeping a handle open will stop
272 windows from reusing the same pid. */
273 if (last_fork_procs[nfork_procs])
274 ForceCloseHandle1 (last_fork_procs[nfork_procs], fork_stupidity);
275 if (DuplicateHandle (hMainProc, h, hMainProc, &last_fork_procs[nfork_procs],
276 0, FALSE, DUPLICATE_SAME_ACCESS))
277 ProtectHandle1 (last_fork_procs[nfork_procs], fork_stupidity);
280 last_fork_procs[nfork_procs] = NULL;
281 system_printf ("couldn't create last_fork_proc, %E");
288 frok::parent (void *stack_here)
290 HANDLE forker_finished;
292 PROCESS_INFORMATION pi = {0, NULL, 0, 0};
296 bool fix_impersonation = false;
299 pthread::atforkprepare ();
301 int c_flags = GetPriorityClass (hMainProc);
302 STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
304 /* If we don't have a console, then don't create a console for the
306 HANDLE console_handle = CreateFile ("CONOUT$", GENERIC_WRITE,
307 FILE_SHARE_WRITE, &sec_none_nih,
308 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
311 if (console_handle != INVALID_HANDLE_VALUE)
312 CloseHandle (console_handle);
314 c_flags |= DETACHED_PROCESS;
316 /* Some file types (currently only sockets) need extra effort in the
317 parent after CreateProcess and before copying the datastructures
318 to the child. So we have to start the child in suspend state,
319 unfortunately, to avoid a race condition. */
320 if (cygheap->fdtab.need_fixup_before ())
321 c_flags |= CREATE_SUSPENDED;
323 /* Remember the address of the first loaded dll and decide
324 if we need to load dlls. We do this here so that this
325 information will be available in the parent and, when
326 the stack is copied, in the child. */
327 first_dll = dlls.start.next;
328 load_dlls = dlls.reload_on_fork && dlls.loaded_dlls;
330 /* This will help some of the confusion. */
333 forker_finished = CreateEvent (&sec_all, FALSE, FALSE, NULL);
334 if (forker_finished == NULL)
336 this_errno = geterrno_from_win_error ();
337 error = "child %d - unable to allocate forker_finished event, %E";
341 ProtectHandleINH (forker_finished);
343 ch.forker_finished = forker_finished;
347 si.cb = sizeof (STARTUPINFO);
348 si.lpReserved2 = (LPBYTE) &ch;
349 si.cbReserved2 = sizeof (ch);
351 /* Remove impersonation */
352 cygheap->user.deimpersonate ();
353 fix_impersonation = true;
355 syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %p, 0, 0, %p, %p)",
356 myself->progname, myself->progname, c_flags, &si, &pi);
357 bool locked = __malloc_lock ();
358 rc = CreateProcess (myself->progname, /* image to run */
359 myself->progname, /* what we send in arg0 */
362 TRUE, /* inherit handles from parent */
364 NULL, /* environment filled in later */
365 0, /* use current drive/directory */
371 this_errno = geterrno_from_win_error ();
372 error = "child %d - CreateProcessA failed, %E";
377 /* Fixup the parent datastructure if needed and resume the child's
379 if (cygheap->fdtab.need_fixup_before ())
381 cygheap->fdtab.fixup_before_fork (pi.dwProcessId);
382 ResumeThread (pi.hThread);
385 child_pid = cygwin_pid (pi.dwProcessId);
386 child.init (child_pid, 1, NULL);
390 this_errno = get_errno () == ENOMEM ? ENOMEM : EAGAIN;
392 error = "child %d - pinfo failed";
394 syscall_printf ("pinfo failed");
399 child->start_time = time (NULL); /* Register child's starting time. */
400 child->nice = myself->nice;
402 /* Initialize things that are done later in dll_crt0_1 that aren't done
404 strcpy (child->progname, myself->progname);
406 /* Restore impersonation */
407 cygheap->user.reimpersonate ();
408 fix_impersonation = false;
410 ProtectHandle (pi.hThread);
411 /* Protect the handle but name it similarly to the way it will
412 be called in subproc handling. */
413 ProtectHandle1 (pi.hProcess, childhProc);
415 /* Fill in fields in the child's process table entry. */
416 child->dwProcessId = pi.dwProcessId;
417 child.hProcess = pi.hProcess;
419 /* Hopefully, this will succeed. The alternative to doing things this
420 way is to reserve space prior to calling CreateProcess and then fill
421 it in afterwards. This requires more bookkeeping than I like, though,
422 so we'll just do it the easy way. So, terminate any child process if
423 we can't actually record the pid in the internal table. */
424 if (!child.remember (false))
426 TerminateProcess (pi.hProcess, 1);
429 error = "child %d - child.remember failed";
434 #ifndef NO_SLOW_PID_REUSE
435 slow_pid_reuse (pi.hProcess);
438 /* Wait for subproc to initialize itself. */
439 if (!ch.sync (child->pid, pi.hProcess, FORK_WAIT_TIMEOUT))
442 error = "child %d - died waiting for longjmp before initialization";
446 /* CHILD IS STOPPED */
447 debug_printf ("child is alive (but stopped)");
449 /* Initialize, in order: data, bss, heap, stack, dll data, dll bss
450 Note: variables marked as NO_COPY will not be copied
451 since they are placed in a protected segment. */
457 if (&_my_tls == _main_tls)
458 impure_beg = impure_end = NULL;
461 impure_beg = _impure_ptr;
462 impure_end = _impure_ptr + 1;
464 rc = fork_copy (pi, "user/cygwin data",
465 user_data->data_start, user_data->data_end,
466 user_data->bss_start, user_data->bss_end,
467 cygheap->user_heap.base, cygheap->user_heap.ptr,
468 stack_here, ch.stackbottom,
469 dll_data_start, dll_data_end,
470 dll_bss_start, dll_bss_end, impure_beg, impure_end, NULL);
478 /* Now fill data/bss of any DLLs that were linked into the program. */
479 for (dll *d = dlls.istart (DLL_LINK); d; d = dlls.inext ())
481 debug_printf ("copying data/bss of a linked dll");
482 if (!fork_copy (pi, "linked dll data/bss", d->p.data_start, d->p.data_end,
483 d->p.bss_start, d->p.bss_end,
486 this_errno = get_errno ();
488 error = "child %d - fork_copy for linked dll data/bss failed";
494 /* Start thread, and wait for it to reload dlls. */
495 if (!resume_child (forker_finished))
497 else if (!ch.sync (child->pid, pi.hProcess, FORK_WAIT_TIMEOUT))
500 error = "child %d died waiting for dll loading";
504 /* If DLLs were loaded in the parent, then the child has reloaded all
505 of them and is now waiting to have all of the individual data and
506 bss sections filled in. */
509 /* CHILD IS STOPPED */
510 /* write memory of reloaded dlls */
511 for (dll *d = dlls.istart (DLL_LOAD); d; d = dlls.inext ())
513 debug_printf ("copying data/bss for a loaded dll");
514 if (!fork_copy (pi, "loaded dll data/bss", d->p.data_start, d->p.data_end,
515 d->p.bss_start, d->p.bss_end,
518 this_errno = get_errno ();
520 error = "child %d - copying data/bss for a loaded dll";
525 /* Start the child up again. */
526 resume_child (forker_finished);
529 ForceCloseHandle (pi.hThread);
530 ForceCloseHandle (forker_finished);
531 forker_finished = NULL;
533 pthread::atforkparent ();
537 /* Common cleanup code for failure cases */
539 if (fix_impersonation)
540 cygheap->user.reimpersonate ();
544 /* Remember to de-allocate the fd table. */
545 if (pi.hProcess && !child.hProcess)
546 ForceCloseHandle1 (pi.hProcess, childhProc);
548 ForceCloseHandle (pi.hThread);
550 ForceCloseHandle (forker_finished);
551 debug_printf ("returning -1");
561 debug_printf ("entering");
562 grouped.first_dll = NULL;
563 grouped.load_dlls = 0;
566 __asm__ volatile ("movl %%esp,%0": "=r" (esp));
568 myself->set_has_pgid_children ();
570 if (grouped.ch.parent == NULL)
572 if (grouped.ch.subproc_ready == NULL)
574 system_printf ("unable to allocate subproc_ready event, %E");
578 sig_send (NULL, __SIGHOLD);
580 int ischild = setjmp (grouped.ch.jmp);
582 res = grouped.parent (esp);
584 res = grouped.child (esp);
587 if (ischild || res > 0)
588 /* everything is ok */;
592 syscall_printf ("fork failed - child pid %d", grouped.child_pid);
594 system_printf (grouped.error, grouped.child_pid);
595 set_errno (grouped.this_errno);
597 syscall_printf ("%d = fork()", res);
598 sig_send (NULL, __SIGNOHOLD);
609 /* Dummy function to force second assignment below to actually be
614 return vfork_storage.val ();
622 debug_printf ("stub called");
625 vfork_save *vf = get_vfork_val ();
629 vf = vfork_storage.create ();
633 // FIXME the tls stuff could introduce a signal race if a child process
638 __asm__ volatile ("movl %%esp,%0": "=r" (vf->vfork_esp):);
639 __asm__ volatile ("movl %%ebp,%0": "=r" (vf->vfork_ebp):);
640 for (pp = (char **) vf->frame, esp = vf->vfork_esp;
641 esp <= vf->vfork_ebp + 2; pp++, esp++)
643 vf->ctty = myself->ctty;
644 vf->sid = myself->sid;
645 vf->pgid = myself->pgid;
646 cygheap->ctty_on_hold = cygheap->ctty;
647 vf->open_fhs = cygheap->open_fhs;
648 debug_printf ("cygheap->ctty_on_hold %p, cygheap->open_fhs %d", cygheap->ctty_on_hold, cygheap->open_fhs);
649 int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1;
650 debug_printf ("%d = vfork()", res);
651 _my_tls.call_signal_handler (); // FIXME: racy
656 vf = get_vfork_val ();
658 for (pp = (char **) vf->frame, esp = vf->vfork_esp;
659 esp <= vf->vfork_ebp + 2; pp++, esp++)
662 cygheap->fdtab.vfork_parent_restore ();
664 myself->ctty = vf->ctty;
665 myself->sid = vf->sid;
666 myself->pgid = vf->pgid;
667 termios_printf ("cygheap->ctty %p, cygheap->ctty_on_hold %p", cygheap->ctty, cygheap->ctty_on_hold);
668 cygheap->open_fhs = vf->open_fhs;
672 int exitval = vf->exitval;
674 if ((vf->pid = fork ()) == 0)
680 debug_printf ("exiting vfork, pid %d", pid);
681 sig_dispatch_pending ();
683 _my_tls.call_signal_handler (); // FIXME: racy
690 child_copy (HANDLE h, DWORD pid, const char *what, void *child_start, void *child_end)
692 PROCESS_INFORMATION pi;
694 pi.dwProcessId = pid;
696 debug_printf ("%s, start %p, end %p", what, child_start, child_end);
697 return fork_copy (pi, what, child_start, child_end, NULL);