3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
20 #include "child_info.h"
23 #include "shared_info.h"
25 #include "cygmalloc.h"
30 /* Timeout to wait for child to start, parent to init child, etc. */
31 /* FIXME: Once things stabilize, bump up to a few minutes. */
32 #define FORK_WAIT_TIMEOUT (300 * 1000) /* 300 seconds */
34 static int dofork (void **proc
, bool *with_forkables
);
37 frok (bool *forkables
)
38 : with_forkables (forkables
)
47 int __stdcall
parent (volatile char * volatile here
);
48 int __stdcall
child (volatile char * volatile here
);
49 bool error (const char *fmt
, ...);
50 friend int dofork (void **proc
, bool *with_forkables
);
54 resume_child (HANDLE forker_finished
)
56 SetEvent (forker_finished
);
57 debug_printf ("signalled child");
61 /* Notify parent that it is time for the next step. */
63 sync_with_parent (const char *s
, bool hang_self
)
65 debug_printf ("signalling parent: %s", s
);
66 fork_info
->ready (false);
69 HANDLE h
= fork_info
->forker_finished
;
70 /* Wait for the parent to fill in our stack and heap.
71 Don't wait forever here. If our parent dies we don't want to clog
72 the system. If the wait fails, we really can't continue so exit. */
73 DWORD psync_rc
= WaitForSingleObject (h
, FORK_WAIT_TIMEOUT
);
74 debug_printf ("awake");
78 api_fatal ("WFSO timed out %s", s
);
81 if (GetLastError () == ERROR_INVALID_HANDLE
&&
82 WaitForSingleObject (fork_info
->forker_finished
, 1) != WAIT_FAILED
)
84 api_fatal ("WFSO failed %s, fork_finished %p, %E", s
,
85 fork_info
->forker_finished
);
88 debug_printf ("no problems");
95 frok::error (const char *fmt
, ...)
97 DWORD exit_code
= ch
.exit_code
;
98 if (!exit_code
&& hchild
)
100 exit_code
= ch
.proc_retry (hchild
);
104 if (exit_code
!= EXITCODE_FORK_FAILED
)
107 static char buf
[NT_MAX_PATH
+ 256];
109 __small_vsprintf (buf
, fmt
, ap
);
115 /* Set up a pipe which will track the life of a "pid" through
116 even after we've exec'ed. */
118 child_info::prefork (bool detached
)
122 if (!CreatePipe (&rd_proc_pipe
, &wr_proc_pipe
, &sec_none_nih
, 16))
123 api_fatal ("prefork: couldn't create pipe process tracker, %E");
125 if (!SetHandleInformation (wr_proc_pipe
, HANDLE_FLAG_INHERIT
,
126 HANDLE_FLAG_INHERIT
))
127 api_fatal ("prefork: couldn't set process pipe(%p) inherit state, %E",
129 ProtectHandle1 (rd_proc_pipe
, rd_proc_pipe
);
130 ProtectHandle1 (wr_proc_pipe
, wr_proc_pipe
);
135 frok::child (volatile char * volatile here
)
137 HANDLE
& hParent
= ch
.parent
;
139 sync_with_parent ("after longjmp", true);
140 debug_printf ("child is running. pid %d, ppid %d, stack here %p",
141 myself
->pid
, myself
->ppid
, __builtin_frame_address (0));
142 sigproc_printf ("hParent %p, load_dlls %d", hParent
, load_dlls
);
144 /* Make sure threadinfo information is properly set up. */
145 if (&_my_tls
!= _main_tls
)
147 _main_tls
= &_my_tls
;
148 _main_tls
->init_thread (NULL
, NULL
);
151 set_cygwin_privileges (hProcToken
);
152 clear_procimptoken ();
153 cygheap
->user
.reimpersonate ();
156 if (GetEnvironmentVariableA ("FORKDEBUG", NULL
, 0))
159 /* This is useful for debugging fork problems. Use gdb to attach to
160 the pid reported here. */
161 if (GetEnvironmentVariableA ("CYGWIN_FORK_SLEEP", buf
, sizeof (buf
)))
163 small_printf ("Sleeping %d after fork, pid %u\n", atoi (buf
), GetCurrentProcessId ());
168 /* Incredible but true: If we use sockets and SYSV IPC shared memory,
169 there's a good chance that a duplicated socket in the child occupies
170 memory which is needed to duplicate shared memory from the parent
171 process, if the shared memory hasn't been duplicated already.
172 The same goes very likely for "normal" mmap shared memory, too, but
173 with SYSV IPC it was the first time observed. So, *never* fixup
174 fdtab before fixing up shared memory. */
175 if (fixup_shms_after_fork ())
176 api_fatal ("recreate_shm areas after fork failed");
178 /* load dynamic dlls, if any, re-track main-executable and cygwin1.dll */
179 dlls
.load_after_fork (hParent
);
181 cygheap
->fdtab
.fixup_after_fork (hParent
);
183 /* Signal that we have successfully initialized, so the parent can
184 - transfer data/bss for dynamically loaded dlls (if any), or
185 - terminate the current fork call even if the child is initialized. */
186 sync_with_parent ("performed fork fixups and dynamic dll loading", true);
188 ForceCloseHandle1 (fork_info
->forker_finished
, forker_finished
);
190 pthread::atforkchild ();
191 cygbench ("fork-child");
193 fixup_hooks_after_fork ();
194 _my_tls
.fixup_after_fork ();
195 /* Clear this or the destructor will close them. In the case of
196 rd_proc_pipe that would be an invalid handle. In the case of
197 wr_proc_pipe it would be == my_wr_proc_pipe. Both would be bad. */
198 ch
.rd_proc_pipe
= ch
.wr_proc_pipe
= NULL
;
199 CloseHandle (hParent
);
201 cygwin_finished_initializing
= true;
206 frok::parent (volatile char * volatile stack_here
)
208 HANDLE forker_finished
;
212 bool fix_impersonation
= false;
215 int c_flags
= GetPriorityClass (GetCurrentProcess ());
216 debug_printf ("priority class %d", c_flags
);
217 /* Per MSDN, this must be specified even if lpEnvironment is set to NULL,
218 otherwise UNICODE characters in the parent environment are not copied
219 correctly to the child. Omitting it may scramble %PATH% on non-English
221 c_flags
|= CREATE_UNICODE_ENVIRONMENT
;
226 /* If we don't have a console, then don't create a console for the
228 HANDLE console_handle
= CreateFile ("CONOUT$", GENERIC_WRITE
,
229 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
230 &sec_none_nih
, OPEN_EXISTING
,
231 FILE_ATTRIBUTE_NORMAL
, NULL
);
233 if (console_handle
!= INVALID_HANDLE_VALUE
)
234 CloseHandle (console_handle
);
236 c_flags
|= DETACHED_PROCESS
;
238 /* Some file types (currently only sockets) need extra effort in the
239 parent after CreateProcess and before copying the datastructures
240 to the child. So we have to start the child in suspend state,
241 unfortunately, to avoid a race condition. */
242 if (cygheap
->fdtab
.need_fixup_before ())
243 c_flags
|= CREATE_SUSPENDED
;
245 /* Remember if we need to load dynamically linked dlls.
246 We do this here so that this information will be available
247 in the parent and, when the stack is copied, in the child. */
248 load_dlls
= dlls
.reload_on_fork
&& dlls
.loaded_dlls
;
250 forker_finished
= CreateEvent (&sec_all
, FALSE
, FALSE
, NULL
);
251 if (forker_finished
== NULL
)
253 this_errno
= geterrno_from_win_error ();
254 error ("unable to allocate forker_finished event");
258 ProtectHandleINH (forker_finished
);
260 ch
.forker_finished
= forker_finished
;
262 ch
.stackbase
= NtCurrentTeb ()->Tib
.StackBase
;
263 ch
.stackaddr
= NtCurrentTeb ()->DeallocationStack
;
266 /* If DeallocationStack is NULL, we're running on an application-provided
267 stack. If so, the entire stack is committed anyway and StackLimit
268 points to the allocation address of the stack. Mark in guardsize that
269 we must not set up guard pages. */
270 ch
.stackaddr
= ch
.stacklimit
= NtCurrentTeb ()->Tib
.StackLimit
;
271 ch
.guardsize
= (size_t) -1;
275 /* Otherwise we're running on a system-allocated stack. Since stack_here
276 is the address of the stack pointer we start the child with anyway, we
277 can set ch.stacklimit to this value rounded down to page size. The
278 child will not need the rest of the stack anyway. Guardsize depends
279 on whether we're running on a pthread or not. If pthread, we fetch
280 the guardpage size from the pthread attribs, otherwise we use the
282 ch
.stacklimit
= (void *) ((uintptr_t) stack_here
& ~(wincap
.page_size () - 1));
283 ch
.guardsize
= (&_my_tls
!= _main_tls
&& _my_tls
.tid
)
284 ? _my_tls
.tid
->attr
.guardsize
285 : wincap
.def_guard_page_size ();
287 debug_printf ("stack - bottom %p, top %p, addr %p, guardsize %ly",
288 ch
.stackbase
, ch
.stacklimit
, ch
.stackaddr
, ch
.guardsize
);
290 PROCESS_INFORMATION pi
;
293 memset (&si
, 0, sizeof (si
));
296 si
.lpReserved2
= (LPBYTE
) &ch
;
297 si
.cbReserved2
= sizeof (ch
);
299 bool locked
= __malloc_lock ();
301 /* Remove impersonation */
302 cygheap
->user
.deimpersonate ();
303 fix_impersonation
= true;
304 ch
.refresh_cygheap ();
305 ch
.prefork (); /* set up process tracking pipes. */
307 *with_forkables
= dlls
.setup_forkables (*with_forkables
);
309 ch
.silentfail (!*with_forkables
); /* fail silently without forkables */
312 PSECURITY_ATTRIBUTES sa
= (PSECURITY_ATTRIBUTES
) tp
.w_get ();
313 if (!sec_user_nih (sa
, cygheap
->user
.saved_sid (),
314 well_known_authenticated_users_sid
,
315 PROCESS_QUERY_LIMITED_INFORMATION
))
320 PCWCHAR forking_progname
= NULL
;
321 if (dlls
.main_executable
)
322 forking_progname
= dll_list::buffered_shortname
323 (dlls
.main_executable
->forkedntname ());
324 if (!forking_progname
|| !*forking_progname
)
325 forking_progname
= myself
->progname
;
327 syscall_printf ("CreateProcessW (%W, %W, 0, 0, 1, %y, 0, 0, %p, %p)",
328 forking_progname
, myself
->progname
, c_flags
, &si
, &pi
);
331 /* cygwin1.dll may reuse the forking_progname buffer, even
332 in case of failure: don't reuse forking_progname later */
333 rc
= CreateProcessW (forking_progname
, /* image to run */
334 GetCommandLineW (), /* Take same space for command
335 line as in parent to make
336 sure child stack is allocated
337 in the same memory location
341 TRUE
, /* inherit handles */
343 NULL
, /* environ filled in later */
349 debug_printf ("forked pid %u", pi
.dwProcessId
);
352 this_errno
= geterrno_from_win_error ();
353 error ("CreateProcessW failed for '%W'", myself
->progname
);
354 dlls
.release_forkables ();
355 memset (&pi
, 0, sizeof (pi
));
359 if (cygheap
->fdtab
.need_fixup_before ())
361 cygheap
->fdtab
.fixup_before_fork (pi
.dwProcessId
);
362 ResumeThread (pi
.hThread
);
365 CloseHandle (pi
.hThread
);
366 hchild
= pi
.hProcess
;
368 dlls
.release_forkables ();
370 /* Protect the handle but name it similarly to the way it will
371 be called in subproc handling. */
372 ProtectHandle1 (hchild
, childhProc
);
374 strace
.write_childpid (pi
.dwProcessId
);
376 /* Wait for subproc to initialize itself. */
377 if (!ch
.sync (pi
.dwProcessId
, hchild
, FORK_WAIT_TIMEOUT
))
379 if (!error ("forked process %u died unexpectedly, retry %d, exit code %y",
380 pi
.dwProcessId
, ch
.retry
, ch
.exit_code
))
388 /* Restore impersonation */
389 cygheap
->user
.reimpersonate ();
390 fix_impersonation
= false;
392 child_pid
= cygwin_pid (pi
.dwProcessId
);
393 child
.init (child_pid
, PID_IN_USE
| PID_NEW
, NULL
);
397 this_errno
= get_errno () == ENOMEM
? ENOMEM
: EAGAIN
;
398 syscall_printf ("pinfo failed");
402 child
->nice
= myself
->nice
;
404 /* Initialize things that are done later in dll_crt0_1 that aren't done
406 wcscpy (child
->progname
, myself
->progname
);
408 /* Fill in fields in the child's process table entry. */
409 child
->dwProcessId
= pi
.dwProcessId
;
410 child
.hProcess
= hchild
;
413 /* Hopefully, this will succeed. The alternative to doing things this
414 way is to reserve space prior to calling CreateProcess and then fill
415 it in afterwards. This requires more bookkeeping than I like, though,
416 so we'll just do it the easy way. So, terminate any child process if
417 we can't actually record the pid in the internal table. */
418 if (!child
.remember (false))
422 error ("child remember failed");
427 /* CHILD IS STOPPED */
428 debug_printf ("child is alive (but stopped)");
431 /* Initialize, in order: stack, dll data, dll bss.
432 data, bss, heap were done earlier (in dcrt0.cc)
433 Note: variables marked as NO_COPY will not be copied since they are
434 placed in a protected segment. */
436 const void *impure_beg
;
437 const void *impure_end
;
439 if (&_my_tls
== _main_tls
)
440 impure_beg
= impure_end
= impure
= NULL
;
444 impure_beg
= _impure_ptr
;
445 impure_end
= _impure_ptr
+ 1;
447 rc
= child_copy (hchild
, true, !*with_forkables
,
448 "stack", stack_here
, ch
.stackbase
,
449 impure
, impure_beg
, impure_end
,
456 this_errno
= get_errno ();
457 error ("pid %u, exitval %p", pi
.dwProcessId
, ch
.exit_code
);
461 /* Now fill data/bss of any DLLs that were linked into the program. */
462 for (dll
*d
= dlls
.istart (DLL_LINK
); d
; d
= dlls
.inext ())
464 debug_printf ("copying data/bss of a linked dll");
465 if (!child_copy (hchild
, true, !*with_forkables
,
466 "linked dll data", d
->p
.data_start
, d
->p
.data_end
,
467 "linked dll bss", d
->p
.bss_start
, d
->p
.bss_end
,
470 this_errno
= get_errno ();
471 error ("couldn't copy linked dll data/bss");
476 /* Start the child up, and then wait for it to
477 perform fork fixups and dynamic dll loading (if any). */
478 resume_child (forker_finished
);
479 if (!ch
.sync (child
->pid
, hchild
, FORK_WAIT_TIMEOUT
))
482 error ("died waiting for dll loading");
486 /* If DLLs were loaded in the parent, then the child has reloaded all
487 of them and is now waiting to have all of the individual data and
488 bss sections filled in. */
491 /* CHILD IS STOPPED */
492 /* write memory of reloaded dlls */
493 for (dll
*d
= dlls
.istart (DLL_LOAD
); d
; d
= dlls
.inext ())
495 debug_printf ("copying data/bss for a loaded dll");
496 if (!child_copy (hchild
, true, !*with_forkables
,
497 "loaded dll data", d
->p
.data_start
, d
->p
.data_end
,
498 "loaded dll bss", d
->p
.bss_start
, d
->p
.bss_end
,
501 this_errno
= get_errno ();
503 error ("copying data/bss for a loaded dll");
510 /* Do not attach to the child before it has successfully initialized.
511 Otherwise we may wait forever, or deliver an orphan SIGCHILD. */
512 if (!child
.attach ())
516 error ("child attach failed");
521 /* Finally start the child up. */
522 resume_child (forker_finished
);
524 ForceCloseHandle (forker_finished
);
525 forker_finished
= NULL
;
529 /* Common cleanup code for failure cases */
531 /* release procinfo before hProcess in destructor */
532 child
.allow_remove ();
534 if (fix_impersonation
)
535 cygheap
->user
.reimpersonate ();
539 /* Remember to de-allocate the fd table. */
542 TerminateProcess (hchild
, 1);
543 if (!child
.hProcess
) /* no child.procinfo */
544 ForceCloseHandle1 (hchild
, childhProc
);
547 ForceCloseHandle (forker_finished
);
548 debug_printf ("returning -1");
555 bool with_forkables
= false; /* do not force hardlinks on first try */
556 int res
= dofork (NULL
, &with_forkables
);
560 return res
; /* no need for second try when already enabled */
561 with_forkables
= true; /* enable hardlinks for second try */
562 return dofork (NULL
, &with_forkables
);
566 /* __posix_spawn_fork is called from newlib's posix_spawn implementation.
567 The original code in newlib has been taken from FreeBSD, and the core
568 code relies on specific, non-portable behaviour of vfork(2). Our
569 replacement implementation needs the forked child's HANDLE for
570 synchronization, so __posix_spawn_fork returns it in proc. */
572 __posix_spawn_fork (void **proc
)
574 bool with_forkables
= false; /* do not force hardlinks on first try */
575 int res
= dofork (proc
, &with_forkables
);
579 return res
; /* no need for second try when already enabled */
580 with_forkables
= true; /* enable hardlinks for second try */
581 return dofork (proc
, &with_forkables
);
585 dofork (void **proc
, bool *with_forkables
)
587 frok
grouped (with_forkables
);
589 debug_printf ("entering");
590 grouped
.load_dlls
= 0;
593 bool ischild
= false;
595 myself
->set_has_pgid_children ();
597 if (grouped
.ch
.parent
== NULL
)
599 if (grouped
.ch
.subproc_ready
== NULL
)
601 system_printf ("unable to allocate subproc_ready event, %E");
606 hold_everything
held_everything (ischild
);
607 /* This tmp_pathbuf constructor is required here because the below setjmp
608 magic will otherwise not restore the original buffer count values in
609 the thread-local storage. A process forking too deeply will run into
610 the problem to be out of temporary TLS path buffers. */
613 if (!held_everything
)
621 /* Put the dll list in topological dependency ordering, in
622 hopes that the child will have a better shot at loading dlls
623 properly if it only has to deal with one at a time. */
626 ischild
= !!setjmp (grouped
.ch
.jmp
);
628 volatile char * volatile stackp
;
630 __asm__
volatile ("movq %%rsp,%0": "=r" (stackp
));
632 __asm__
volatile ("movl %%esp,%0": "=r" (stackp
));
636 res
= grouped
.parent (stackp
);
639 res
= grouped
.child (stackp
);
641 ischild
= true; /* might have been reset by fork mem copy */
647 myself
->process_state
|= PID_ACTIVE
;
648 myself
->process_state
&= ~(PID_INITIALIZING
| PID_EXITED
| PID_REAPED
);
653 syscall_printf ("fork failed - child pid %d, errno %d", grouped
.child_pid
, grouped
.this_errno
);
654 else if (grouped
.ch
.silentfail ())
655 debug_printf ("child %d - %s, errno %d", grouped
.child_pid
,
656 grouped
.errmsg
, grouped
.this_errno
);
658 system_printf ("child %d - %s, errno %d", grouped
.child_pid
,
659 grouped
.errmsg
, grouped
.this_errno
);
661 set_errno (grouped
.this_errno
);
665 /* Return child process handle to posix_fork. */
666 *proc
= grouped
.hchild
;
668 syscall_printf ("%R = fork()", res
);
682 debug_printf ("stub called");
686 /* Copy memory from one process to another. */
689 child_copy (HANDLE hp
, bool write
, bool silentfail
, ...)
692 va_start (args
, silentfail
);
693 static const char *huh
[] = {"read", "write"};
696 while ((what
= va_arg (args
, char *)))
698 char *low
= va_arg (args
, char *);
699 char *high
= va_arg (args
, char *);
700 SIZE_T todo
= high
- low
;
703 for (here
= low
; here
< high
; here
+= todo
)
706 if (here
+ todo
> high
)
710 res
= WriteProcessMemory (hp
, here
, here
, todo
, &done
);
712 res
= ReadProcessMemory (hp
, here
, here
, todo
, &done
);
713 debug_printf ("%s - hp %p low %p, high %p, res %d", what
, hp
, low
, high
, res
);
714 if (!res
|| todo
!= done
)
719 debug_printf ("%s %s copy failed, %p..%p, done %lu, windows pid %u, %E",
720 what
, huh
[write
], low
, high
, done
, myself
->dwProcessId
);
722 /* If this happens then there is a bug in our fork
723 implementation somewhere. */
724 system_printf ("%s %s copy failed, %p..%p, done %lu, windows pid %u, %E",
725 what
, huh
[write
], low
, high
, done
, myself
->dwProcessId
);
732 debug_printf ("done");
737 TerminateProcess (hp
, 1);