1 /* sigproc.cc: inter/intra signal and sub process handler
3 Copyright 1997, 1998, 1999, 2000 Cygnus Solutions.
5 Written by Christopher Faylor <cgf@cygnus.com>
7 This file is part of Cygwin.
9 This software is a copyrighted work licensed under the terms of the
10 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
21 extern BOOL allow_ntsec;
26 #define WSSC 60000 // Wait for signal completion
27 #define WPSP 40000 // Wait for proc_subproc mutex
28 #define WSPX 20000 // Wait for wait_sig to terminate
29 #define WWSP 20000 // Wait for wait_subproc to terminate
31 #define WAIT_SIG_PRIORITY THREAD_PRIORITY_NORMAL
33 #define TOTSIGS (NSIG + __SIGOFFSET)
35 #define sip_printf(fmt, args...) sigproc_printf (fmt , ## args)
37 #define wake_wait_subproc() SetEvent (events[0])
39 #define no_signals_available() (!hwait_sig || !sig_loop_wait)
47 char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes to
48 // current process but no wait is required
49 char NO_COPY myself_nowait_nonmain_dummy[1] = {'1'};// Flag to sig_send that signal goes to
50 // current process but no wait is required
51 // if this is not the main thread.
53 HANDLE NO_COPY signal_arrived; // Event signaled when a signal has
54 // resulted in a user-specified
61 /* How long to wait for message/signals. Normally this is infinite.
62 * On termination, however, these are set to zero as a flag to exit.
65 #define Static static NO_COPY
67 Static DWORD proc_loop_wait = 500; // Wait for subprocesses to exit
68 Static DWORD sig_loop_wait = 500; // Wait for signals to arrive
70 Static HANDLE sigcatch_nonmain = NULL; // The semaphore signaled when
71 // signals are available for
72 // processing from non-main thread
73 Static HANDLE sigcatch_main = NULL; // Signalled when main thread sends a
75 Static HANDLE sigcatch_nosync = NULL; // Signal wait_sig to scan sigtodo
76 // but not to bother with any
78 Static HANDLE sigcomplete_main = NULL; // Event signaled when a signal has
79 // finished processing for the main
81 Static HANDLE sigcomplete_nonmain = NULL;// Semaphore raised for non-main
82 // threads when a signal has finished
84 Static HANDLE hwait_sig = NULL; // Handle of wait_sig thread
85 Static HANDLE hwait_subproc = NULL; // Handle of sig_subproc thread
87 Static HANDLE wait_sig_inited = NULL; // Control synchronization of
88 // message queue startup
90 /* Used by WaitForMultipleObjects. These are handles to child processes.
92 Static HANDLE events[PSIZE + 1] = {0}; // All my children's handles++
93 #define hchildren (events + 1) // Where the children handles begin
94 Static pinfo *pchildren[PSIZE] = {NULL};// All my children info
95 Static pinfo *zombies[PSIZE] = {NULL}; // All my deceased children info
96 Static int nchildren = 0; // Number of active children
97 Static int nzombies = 0; // Number of deceased children
99 Static waitq waitq_head = {0, 0, 0, 0, 0, 0, 0};// Start of queue for wait'ing threads
100 Static waitq waitq_main; // Storage for main thread
102 muto NO_COPY *sync_proc_subproc = NULL; // Control access to subproc stuff
104 DWORD NO_COPY maintid = 0; // ID of the main thread
105 DWORD NO_COPY sigtid = 0; // ID of the signal thread
107 int NO_COPY pending_signals = 0; // TRUE if signals pending
111 static int __stdcall checkstate (waitq *);
112 static __inline__ BOOL get_proc_lock (DWORD, DWORD);
113 static HANDLE __stdcall getsem (pinfo *, const char *, int, int);
114 static void __stdcall remove_child (int);
115 static void __stdcall remove_zombie (int);
116 static DWORD WINAPI wait_sig (VOID *arg);
117 static int __stdcall stopped_or_terminated (waitq *, pinfo *);
118 static DWORD WINAPI wait_subproc (VOID *);
120 /* Determine if the parent process is alive.
124 my_parent_is_alive ()
129 debug_printf ("No parent_alive mutex");
133 for (int i = 0; i < 2; i++)
134 switch (res = WaitForSingleObject (parent_alive, 0))
137 debug_printf ("parent dead.");
141 debug_printf ("parent still alive");
145 DWORD werr = GetLastError ();
146 if (werr == ERROR_INVALID_HANDLE && i == 0)
148 system_printf ("WFSO for parent_alive(%p) failed, error %d",
160 /* See if this is the first signal call after initialization.
161 * If so, wait for notification that all initialization has completed.
162 * Then set the handle to NULL to avoid checking this again.
166 (void) WaitForSingleObject (wait_sig_inited, INFINITE);
167 (void) ForceCloseHandle (wait_sig_inited);
168 wait_sig_inited = NULL;
172 static BOOL __stdcall
173 proc_can_be_signalled (pinfo *p)
175 if (p == myself_nowait || p == myself_nowait_nonmain || p == myself)
181 return ISSTATE (p, PID_INITIALIZING) ||
182 (((p)->process_state & (PID_ACTIVE | PID_IN_USE)) ==
183 (PID_ACTIVE | PID_IN_USE));
186 /* Test to determine if a process really exists and is processing
190 proc_exists (pinfo *p)
197 if (p == myself || p == myself_nowait_nonmain || p == myself_nowait)
200 if (p->process_state == PID_NOT_IN_USE || !p->dwProcessId)
203 sip_printf ("checking for existence of pid %d, window pid %d", p->pid,
205 if (p->ppid == myself->pid && p->hProcess != NULL)
207 sip_printf ("it's mine, process_state %x", p->process_state);
208 return proc_can_be_signalled (p);
211 /* Note: Process is alive if OpenProcess() call fails due to permissions */
212 if (((h = OpenProcess (STANDARD_RIGHTS_REQUIRED, FALSE, p->dwProcessId))
213 != NULL) || (GetLastError () == ERROR_ACCESS_DENIED))
215 sip_printf ("it exists, %p", h);
218 DWORD rc = WaitForSingleObject (h, 0);
220 if (rc == WAIT_OBJECT_0)
223 return proc_can_be_signalled (p);
226 sip_printf ("it doesn't exist");
227 /* If the parent pid does not exist, clean this process out of the pinfo
228 * table. It must have died abnormally.
230 if ((p->pid == p->ppid) || (p->ppid == 1) || !proc_exists (procinfo (p->ppid)))
233 p->process_state = PID_NOT_IN_USE;
238 /* Handle all subprocess requests
240 #define vchild ((pinfo *) val)
242 proc_subproc (DWORD what, DWORD val)
251 #define wval ((waitq *) val)
253 sip_printf ("args: %x, %d", what, val);
255 if (!get_proc_lock (what, val)) // Serialize access to this function
257 sip_printf ("I am not ready");
263 /* Add a new subprocess to the children arrays.
264 * (usually called from the main thread)
267 if (nchildren >= PSIZE - 1)
268 system_printf ("nchildren too large %d", nchildren);
269 if (WaitForSingleObject (vchild->hProcess, 0) != WAIT_TIMEOUT)
271 system_printf ("invalid process handle %p. pid %d, win pid %d",
272 vchild->hProcess, vchild->pid, vchild->dwProcessId);
277 pchildren[nchildren] = vchild;
278 hchildren[nchildren] = vchild->hProcess;
279 ProtectHandle (vchild->hProcess);
280 sip_printf ("added pid %d to wait list, slot %d, winpid %p, handle %p",
281 vchild->pid, nchildren, vchild->dwProcessId,
285 wake_wait_subproc ();
288 /* A child process had terminated.
289 * Possibly this is just due to an exec(). Cygwin implements an exec()
290 * as a "handoff" from one windows process to another. If child->hProcess
291 * is different from what is recorded in hchildren, then this is an exec().
292 * Otherwise this is a normal child termination event.
293 * (called from wait_subproc thread)
295 case PROC_CHILDTERMINATED:
297 child = pchildren[val];
298 if (GetExitCodeProcess (hchildren[val], &exitcode) &&
299 hchildren[val] != child->hProcess)
301 sip_printf ("pid %d[%d], reparented old hProcess %p, new %p",
302 child->pid, val, hchildren[val], child->hProcess);
303 ForceCloseHandle1 (hchildren[val], childhProc);
304 hchildren[val] = child->hProcess; /* Filled out by child */
305 ProtectHandle1 (child->hProcess, childhProc);
306 break; // This was an exec()
309 sip_printf ("pid %d[%d] terminated, handle %p, nchildren %d, nzombies %d",
310 child->pid, val, hchildren[val], nchildren, nzombies);
311 remove_child (val); // Remove from children arrays
312 zombies[nzombies++] = child; // Add to zombie array
313 child->process_state = PID_ZOMBIE;// Walking dead
314 if (!proc_loop_wait) // Don't bother if wait_subproc is
317 /* Send a SIGCHLD to myself. */
318 rc = sig_send (myself_nowait, SIGCHLD); // Send a SIGCHLD
321 /* A child is in the stopped state. Scan wait() queue to see if anyone
322 * should be notified. (Called from wait_sig thread)
324 case PROC_CHILDSTOPPED:
325 child = myself; // Just to avoid accidental NULL dereference
326 sip_printf ("Received stopped notification");
330 /* Clear all waiting threads. Called from exceptions.cc prior to
331 * the main thread's dispatch to a signal handler function.
332 * (called from wait_sig thread)
335 /* Clear all "wait"ing threads. */
337 sip_printf ("clear waiting threads");
339 sip_printf ("looking for processes to reap");
343 /* Scan the linked list of wait()ing threads. If a wait's parameters
344 * match this pid, then activate it.
346 for (w = &waitq_head; w->next != NULL; w = w->next)
348 if ((potential_match = checkstate (w)) > 0)
349 sip_printf ("released waiting thread");
350 else if (!clearing && potential_match < 0)
351 sip_printf ("only found non-terminated children");
352 else if (potential_match <= 0) // nothing matched
354 sip_printf ("waiting thread found no children");
355 HANDLE oldw = w->next->ev;
357 w->next->status = -1; /* flag that a signal was received */
360 if (!SetEvent (oldw))
361 system_printf ("couldn't wake up wait event %p, %E", oldw);
362 w->next = w->next->next;
369 sip_printf ("finished processing terminated/stopped child");
372 waitq_head.next = NULL;
373 sip_printf ("finished clearing");
377 /* Handle a wait4() operation. Allocates an event for the calling
378 * thread which is signaled when the appropriate pid exits or stops.
379 * (usually called from the main thread)
382 wval->ev = NULL; // Don't know event flag yet
385 child = NULL; // Not looking for a specific pid
386 else if ((child = procinfo (wval->pid)) == NULL)
387 goto out; // invalid pid. flag no such child
389 wval->status = 0; // Don't know status yet
391 /* Put waitq structure at the end of a linked list. */
392 for (w = &waitq_head; w->next != NULL; w = w->next)
393 if (w->next == wval && (w->next = w->next->next) == NULL)
396 wval->next = NULL; /* This will be last in the list */
397 sip_printf ("wval->pid %d, wval->options %d", wval->pid, wval->options);
399 /* If the first time for this thread, create a new event, otherwise
402 if ((wval->ev = wval->thread_ev) == NULL)
404 wval->ev = wval->thread_ev = CreateEvent (&sec_none_nih, TRUE,
406 ProtectHandle (wval->ev);
408 ResetEvent (wval->ev);
410 /* Scan list of children to see if any have died.
411 * If so, the event flag is set so that the wait* ()
412 * process will return immediately.
414 * If no children were found and the wait option was WNOHANG,
415 * then set the pid to 0 and remove the waitq value from
418 w->next = wval; /* set at end of wait queue */
419 if ((potential_match = checkstate (w)) <= 0)
421 if (!potential_match)
423 w->next = NULL; // don't want to keep looking
424 wval->ev = NULL; // flag that there are no children
425 sip_printf ("no appropriate children, %p, %p",
426 wval->thread_ev, wval->ev);
428 else if (wval->options & WNOHANG)
430 w->next = NULL; // don't want to keep looking
431 wval->pid = 0; // didn't find a pid
432 if (!SetEvent (wval->ev)) // wake up wait4 () immediately
433 system_printf ("Couldn't wake up wait event, %E");
434 sip_printf ("WNOHANG and no terminated children, %p, %p",
435 wval->thread_ev, wval->ev);
439 sip_printf ("wait activated %p, %p", wval->thread_ev, wval->ev);
440 else if (wval->ev != NULL)
441 sip_printf ("wait activated %p. Reaped zombie.", wval->ev);
443 sip_printf ("wait not activated %p, %p", wval->thread_ev, wval->ev);
448 sync_proc_subproc->release (); // Release the lock
450 sip_printf ("returning %d", rc);
454 /* Terminate the wait_subproc thread.
455 * Called on process exit.
456 * Also called by spawn_guts to disassociate any subprocesses from this
457 * process. Subprocesses will then know to clean up after themselves and
458 * will not become zombies.
461 proc_terminate (void)
463 sip_printf ("nchildren %d, nzombies %d", nchildren, nzombies);
464 /* Signal processing is assumed to be blocked in this routine. */
468 proc_loop_wait = 0; // Tell wait_subproc thread to exit
469 wake_wait_subproc (); // Wake wait_subproc loop
471 /* Wait for wait_subproc thread to exit (but not *too* long) */
472 if ((rc = WaitForSingleObject (hwait_subproc, WWSP)) != WAIT_OBJECT_0)
473 if (rc == WAIT_TIMEOUT)
474 system_printf ("WFSO(hwait_subproc) timed out");
476 system_printf ("WFSO(hwait_subproc), rc %d, %E", rc);
478 HANDLE h = hwait_subproc;
479 hwait_subproc = NULL;
480 ForceCloseHandle1 (h, hwait_subproc);
482 sync_proc_subproc->acquire(WPSP);
483 (void) proc_subproc (PROC_CLEARWAIT, 1);
485 lock_pinfo_for_update (INFINITE);
486 /* Clean out zombie processes from the pid list. */
488 for (i = 0; i < nzombies; i++)
491 if ((child = zombies[i])->hProcess)
493 ForceCloseHandle1 (child->hProcess, childhProc);
494 child->hProcess = NULL;
496 child->process_state = PID_NOT_IN_USE;
499 /* Disassociate my subprocesses */
500 for (i = 0; i < nchildren; i++)
503 if ((child = pchildren[i])->process_state == PID_NOT_IN_USE)
504 continue; // Should never happen
505 if (!child->hProcess)
506 sip_printf ("%d(%d) hProcess cleared already?", child->pid,
510 ForceCloseHandle1 (child->hProcess, childhProc);
511 child->hProcess = NULL;
512 if (!proc_exists (child))
514 sip_printf ("%d(%d) doesn't exist", child->pid,
516 child->process_state = PID_NOT_IN_USE; /* a reaped child */
520 sip_printf ("%d(%d) closing active child handle", child->pid,
523 if (child->pgid == myself->pid)
524 child->process_state |= PID_ORPHANED;
529 nchildren = nzombies = 0;
531 /* Attempt to close and release sync_proc_subproc in a
532 * non-raceable manner.
534 muto *m = sync_proc_subproc;
537 sync_proc_subproc = NULL;
541 sip_printf ("leaving");
544 /* Clear pending signal from the sigtodo array
549 (void) InterlockedExchange (myself->getsigtodo(sig), 0L);
553 /* Force the wait_sig thread to wake up and scan the sigtodo array.
555 extern "C" int __stdcall
556 sig_dispatch_pending (int justwake)
561 int was_pending = pending_signals;
563 sip_printf ("pending_signals %d", was_pending);
565 if (!was_pending && !justwake)
567 sip_printf ("no need to wake anything up");
575 (void) sig_send (myself, __SIGFLUSH);
576 else if (ReleaseSemaphore (sigcatch_nosync, 1, NULL))
578 sip_printf ("woke up wait_sig");
582 else if (no_signals_available ())
583 /*sip_printf ("I'm going away now")*/;
585 system_printf ("%E releasing sigcatch_nosync(%p)", sigcatch_nosync);
591 /* Message initialization. Called from dll_crt0_1
593 * This routine starts the signal handling thread. The wait_sig_inited
594 * event is used to signal that the thread is ready to handle signals.
595 * We don't wait for this during initialization but instead detect it
596 * in sig_send to gain a little concurrency.
601 wait_sig_inited = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
602 ProtectHandle (wait_sig_inited);
604 /* local event signaled when main thread has been dispatched
605 to a signal handler function. */
606 signal_arrived = CreateEvent(&sec_none_nih, TRUE, FALSE, NULL);
608 maintid = GetCurrentThreadId ();// For use in determining if signals
609 // should be blocked.
611 if (!(hwait_sig = makethread (wait_sig, NULL, 0, "sig")))
613 system_printf ("cannot create wait_sig thread, %E");
614 api_fatal ("terminating");
617 ProtectHandle (hwait_sig);
619 /* sync_proc_subproc is used by proc_subproc. It serialises
620 * access to the children and zombie arrays.
622 sync_proc_subproc = new_muto (FALSE, "sync_proc_subproc");
624 /* Initialize waitq structure for main thread. A waitq structure is
625 * allocated for each thread that executes a wait to allow multiple threads
626 * to perform waits. Pre-allocate a waitq structure for the main thread.
629 if ((w = (waitq *)waitq_storage.get ()) == NULL)
632 waitq_storage.set (w);
634 memset (w, 0, sizeof *w); // Just to be safe
636 sip_printf ("process/signal handling enabled(%x)", myself->process_state);
640 /* Called on process termination to terminate signal and process threads.
643 sigproc_terminate (void)
645 HANDLE h = hwait_sig;
648 if (GetCurrentThreadId () == sigtid)
650 ForceCloseHandle (sigcomplete_main);
651 for (int i = 0; i < 20; i++)
652 (void) ReleaseSemaphore (sigcomplete_nonmain, 1, NULL);
653 ForceCloseHandle (sigcomplete_nonmain);
654 ForceCloseHandle (sigcatch_main);
655 ForceCloseHandle (sigcatch_nonmain);
656 ForceCloseHandle (sigcatch_nosync);
658 proc_terminate (); // Terminate process handling thread
661 sip_printf ("sigproc_terminate: sigproc handling not active");
664 sigproc_printf ("entering");
665 sig_loop_wait = 0; // Tell wait_sig to exit when it is
666 // finished with anything it is doing
667 sig_dispatch_pending (TRUE); // wake up and die
669 /* If !hwait_sig, then the process probably hasn't even finished
670 * its initialization phase.
674 if (GetCurrentThreadId () != sigtid)
675 WaitForSingleObject (h, 10000);
676 ForceCloseHandle1 (h, hwait_sig);
678 /* Exiting thread. Cleanup. Don't set to inactive if a child has been
679 execed with the same pid. */
680 if (!myself->dwProcessId || myself->dwProcessId == GetCurrentProcessId ())
681 myself->process_state &= ~PID_ACTIVE;
683 sip_printf ("Did not clear PID_ACTIVE since %d != %d",
684 myself->dwProcessId, GetCurrentProcessId ());
686 /* In case of a sigsuspend */
687 SetEvent (signal_arrived);
689 if (GetCurrentThreadId () != sigtid)
691 ForceCloseHandle (sigcomplete_main);
692 ForceCloseHandle (sigcomplete_nonmain);
693 ForceCloseHandle (sigcatch_main);
694 ForceCloseHandle (sigcatch_nonmain);
695 ForceCloseHandle (sigcatch_nosync);
701 /* Set this so that subsequent tests will succeed. */
702 if (!myself->dwProcessId)
703 myself->dwProcessId = GetCurrentProcessId ();
708 /* Send a signal to another process by raising its signal semaphore.
709 * If pinfo *p == NULL, send to the current process.
710 * If sending to this process, wait for notification that a signal has
711 * completed before returning.
714 sig_send (pinfo *p, int sig, DWORD ebp)
717 DWORD tid = GetCurrentThreadId ();
719 HANDLE thiscatch = NULL;
720 HANDLE thiscomplete = NULL;
721 BOOL wait_for_completion;
722 extern signal_dispatch sigsave;
724 if (p == myself_nowait_nonmain)
725 p = (tid == maintid) ? myself : myself_nowait;
726 if (!(its_me = (p == NULL || p == myself || p == myself_nowait)))
727 wait_for_completion = FALSE;
730 if (no_signals_available ())
731 goto out; // Either exiting or not yet initializing
733 wait_for_completion = p != myself_nowait;
737 /* It is possible that the process is not yet ready to receive messages
738 * or that it has exited. Detect this.
740 if (!proc_can_be_signalled (p)) /* Is the process accepting messages? */
742 sip_printf ("invalid pid %d(%x), signal %d",
743 p->pid, p->process_state, sig);
748 sip_printf ("pid %d, signal %d, its_me %d", p->pid, sig, its_me);
752 if (!wait_for_completion)
753 thiscatch = sigcatch_nosync;
754 else if (tid != maintid)
756 thiscatch = sigcatch_nonmain;
757 thiscomplete = sigcomplete_nonmain;
761 thiscatch = sigcatch_main;
762 thiscomplete = sigcomplete_main;
763 sigsave.ebp = ebp ?: (DWORD) __builtin_frame_address (1);
766 else if (!(thiscatch = getsem (p, "sigcatch", 0, 0)))
767 goto out; // Couldn't get the semaphore. getsem issued
768 // an error, if appropriate.
770 #if WHEN_MULTI_THREAD_SIGNALS_WORK
772 sd = signal_dispatch_storage.get ();
774 sd = signal_dispatch_storage.create ();
777 /* Increment the sigtodo array to signify which signal to assert.
779 (void) InterlockedIncrement (p->getsigtodo(sig));
781 /* Notify the process that a signal has arrived.
787 prio = GetThreadPriority (GetCurrentThread ());
788 (void) SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
791 if (!ReleaseSemaphore (thiscatch, 1, NULL) && (int) GetLastError () > 0)
793 sigproc_printf ("ReleaseSemaphore failed, %E");
794 /* Couldn't signal the semaphore. This probably means that the
795 * process is exiting.
798 ForceCloseHandle (thiscatch);
801 if (no_signals_available ())
802 sip_printf ("I'm going away now");
803 else if ((int) GetLastError () == -1)
804 rc = WaitForSingleObject (thiscomplete, 500);
806 system_printf ("error sending signal %d to pid %d, semaphore %p, %E",
807 sig, p->pid, thiscatch);
811 sigproc_printf ("ReleaseSemaphore succeeded");
813 /* No need to wait for signal completion unless this was a signal to
816 * If it was a signal to this process, wait for a dispatched signal.
817 * Otherwise just wait for the wait_sig to signal that it has finished
818 * processing the signal.
820 if (!wait_for_completion)
823 sip_printf ("Not waiting for sigcomplete. its_me %d sig %d", its_me, sig);
825 ForceCloseHandle (thiscatch);
829 sip_printf ("Waiting for thiscomplete %p", thiscomplete);
832 rc = WaitForSingleObject (thiscomplete, WSSC);
833 /* Check for strangeness due to this thread being redirected by the
834 signal handler. Sometimes a WAIT_TIMEOUT will occur when the
835 thread hasn't really timed out. So, check again.
836 FIXME: This isn't foolproof. */
837 if (rc != WAIT_OBJECT_0 &&
838 WaitForSingleObject (thiscomplete, 0) == WAIT_OBJECT_0)
843 SetThreadPriority (GetCurrentThread (), prio);
846 if (rc == WAIT_OBJECT_0)
847 rc = 0; // Successful exit
850 /* It's an error unless sig_loop_wait == 0 (the process is exiting). */
851 if (!no_signals_available ())
852 system_printf ("wait for sig_complete event failed, sig %d, rc %d, %E",
859 sip_printf ("returning %d from sending signal %d", rc, sig);
863 /* Set pending signal from the sigtodo array
866 sig_set_pending (int sig)
868 (void) InterlockedIncrement (myself->getsigtodo(sig));
872 /* Initialize the wait_subproc thread.
873 * Called from fork() or spawn() to initialize the handling of subprocesses.
881 /* A "wakeup" handle which can be toggled to make wait_subproc reexamine
882 * the hchildren array.
884 events[0] = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
885 if (!(hwait_subproc = makethread (wait_subproc, NULL, 0, "+proc")))
886 system_printf ("cannot create wait_subproc thread, %E");
887 ProtectHandle (events[0]);
888 ProtectHandle (hwait_subproc);
889 sip_printf ("started wait_subproc thread %p", hwait_subproc);
892 /* Initialize some of the memory block passed to child processes
893 by fork/spawn/exec. */
896 init_child_info (DWORD chtype, child_info *ch, int pid, HANDLE subproc_ready)
899 memset (ch, 0, sizeof *ch);
903 ch->shared_h = cygwin_shared_h;
904 ch->console_h = console_shared_h;
905 ch->subproc_ready = subproc_ready;
906 if (chtype != PROC_EXEC || !parent_alive)
907 ch->parent_alive = hwait_subproc;
908 else if (parent_alive)
909 DuplicateHandle (hMainProc, parent_alive, hMainProc, &ch->parent_alive,
910 0, 1, DUPLICATE_SAME_ACCESS);
913 /* Check the state of all of our children to see if any are stopped or
917 checkstate (waitq *w)
919 int i, x, potential_match = 0;
922 sip_printf ("nchildren %d, nzombies %d", nchildren, nzombies);
924 /* Check already dead processes first to see if they match the criteria
927 for (i = 0; i < nzombies; i++)
928 if ((x = stopped_or_terminated (w, child = zombies[i])) < 0)
929 potential_match = -1;
937 sip_printf ("checking alive children");
939 /* No dead terminated children matched. Check for stopped children. */
940 for (i = 0; i < nchildren; i++)
941 if ((x = stopped_or_terminated (w, pchildren[i])) < 0)
942 potential_match = -1;
950 sip_printf ("returning %d", potential_match);
951 return potential_match;
954 /* Get or create a process specific semaphore used in message passing.
956 static HANDLE __stdcall
957 getsem (pinfo *p, const char *str, int init, int max)
963 if (!proc_can_be_signalled (p))
969 sip_printf ("pid %d, ppid %d, wait %d, initializing %x", p->pid, p->ppid, wait,
970 ISSTATE (p, PID_INITIALIZING));
971 for (int i = 0; ISSTATE (p, PID_INITIALIZING) && i < wait; i++)
980 DWORD winpid = GetCurrentProcessId ();
981 h = CreateSemaphore (allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
982 init, max, str = shared_name (str, winpid));
987 h = OpenSemaphore (SEMAPHORE_ALL_ACCESS, FALSE,
988 str = shared_name (str, p->dwProcessId));
992 if (GetLastError () == ERROR_FILE_NOT_FOUND && !proc_exists (p))
1002 system_printf ("can't %s %s, %E", p ? "open" : "create", str);
1008 /* Get the sync_proc_subproc muto to control access to
1009 * children, zombie arrays.
1010 * Attempt to handle case where process is exiting as we try to grab
1013 static __inline__ BOOL
1014 get_proc_lock (DWORD what, DWORD val)
1016 Static int lastwhat = -1;
1017 if (!sync_proc_subproc)
1019 if (sync_proc_subproc->acquire (WPSP))
1024 if (!sync_proc_subproc)
1026 system_printf ("Couldn't aquire sync_proc_subproc for(%d,%d), %E, last %d",
1027 what, val, lastwhat);
1031 /* Remove a child from pchildren/hchildren by swapping it with the
1032 * last child in the list.
1034 static void __stdcall
1035 remove_child (int ci)
1037 sip_printf ("removing [%d], pid %d, handle %p, nchildren %d",
1038 ci, pchildren[ci]->pid, hchildren[ci], nchildren);
1039 if (ci < --nchildren)
1041 pchildren[ci] = pchildren[nchildren];
1042 hchildren[ci] = hchildren[nchildren];
1048 /* Remove a zombie from zombies by swapping it with the last child in the list.
1050 static void __stdcall
1051 remove_zombie (int ci)
1053 sip_printf ("removing %d, pid %d, nzombies %d", ci, zombies[ci]->pid,
1055 if (ci < --nzombies)
1056 zombies[ci] = zombies[nzombies];
1061 /* Check status of child process vs. waitq member.
1063 * parent_w is the pointer to the parent of the waitq member in question.
1064 * child is the subprocess being considered.
1067 * 1 if stopped or terminated child matches parent_w->next criteria
1068 * -1 if a non-stopped/terminated child matches parent_w->next criteria
1069 * 0 if child does not match parent_w->next criteria
1071 static int __stdcall
1072 stopped_or_terminated (waitq *parent_w, pinfo *child)
1074 int potential_match;
1075 waitq *w = parent_w->next;
1077 sip_printf ("considering pid %d", child->pid);
1079 potential_match = 1;
1080 else if (w->pid == 0)
1081 potential_match = child->pgid == myself->pgid;
1082 else if (w->pid < 0)
1083 potential_match = child->pgid == -w->pid;
1085 potential_match = (w->pid == child->pid);
1087 if (!potential_match)
1092 if ((terminated = child->process_state == PID_ZOMBIE) ||
1093 (w->options & WUNTRACED) && child->stopsig)
1095 parent_w->next = w->next; /* successful wait. remove from wait queue */
1096 w->pid = child->pid;
1100 sip_printf ("stopped child");
1101 w->status = (child->stopsig << 8) | 0x7f;
1107 if (!GetExitCodeProcess (child->hProcess, &status))
1109 if (status & EXIT_SIGNAL)
1110 w->status = (status >> 8) & 0xff; /* exited due to signal */
1112 w->status = (status & 0xff) << 8; /* exited via "exit ()" */
1114 add_rusage (&myself->rusage_children, &child->rusage_children);
1115 add_rusage (&myself->rusage_children, &child->rusage_self);
1119 add_rusage ((struct rusage *) w->rusage, &child->rusage_children);
1120 add_rusage ((struct rusage *) w->rusage, &child->rusage_self);
1122 ForceCloseHandle1 (child->hProcess, childhProc);
1123 child->hProcess = NULL;
1124 child->process_state = PID_NOT_IN_USE; /* a reaped child */
1127 if (!SetEvent (w->ev)) /* wake up wait4 () immediately */
1128 system_printf ("couldn't wake up wait event %p, %E", w->ev);
1132 return -potential_match;
1135 /* Process signals by waiting for a semaphore to become signaled.
1136 * Then scan an in-memory array representing queued signals.
1137 * Executes in a separate thread.
1139 * Signals sent from this process are sent a completion signal so
1140 * that returns from kill/raise do not occur until the signal has
1141 * has been handled, as per POSIX.
1146 /* Initialization */
1147 (void) SetThreadPriority (hwait_sig, WAIT_SIG_PRIORITY);
1149 /* sigcatch_nosync - semaphore incremented by sig_dispatch_pending and
1150 * by foreign processes to force an examination of
1151 * the sigtodo array.
1152 * sigcatch_main - ditto for local main thread.
1153 * sigcatch_nonmain - ditto for local non-main threads.
1155 * sigcomplete_main - event used to signal main thread on signal
1157 * sigcomplete_nonmain - semaphore signaled for non-main thread on signal
1160 sigcatch_nosync = getsem (NULL, "sigcatch", 0, MAXLONG);
1161 sigcatch_nonmain = CreateSemaphore (&sec_none_nih, 0, MAXLONG, NULL);
1162 sigcatch_main = CreateSemaphore (&sec_none_nih, 0, MAXLONG, NULL);
1163 sigcomplete_nonmain = CreateSemaphore (&sec_none_nih, 0, MAXLONG, NULL);
1164 sigcomplete_main = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
1165 sigproc_printf ("sigcatch_nonmain %p", sigcatch_nonmain);
1167 /* Setting dwProcessId flags that this process is now capable of receiving
1168 * signals. Prior to this, dwProcessId was set to the windows pid of
1169 * of the original windows process which spawned us unless this was a
1170 * "toplevel" process.
1172 myself->dwProcessId = GetCurrentProcessId ();
1173 myself->process_state |= PID_ACTIVE;
1174 myself->process_state &= ~PID_INITIALIZING;
1176 ProtectHandle (sigcatch_nosync);
1177 ProtectHandle (sigcatch_nonmain);
1178 ProtectHandle (sigcatch_main);
1179 ProtectHandle (sigcomplete_nonmain);
1180 ProtectHandle (sigcomplete_main);
1182 /* If we've been execed, then there is still a stub left in the previous
1183 * windows process waiting to see if it's started a cygwin process or not.
1184 * Signalling subproc_ready indicates that we are a cygwin process.
1186 if (child_proc_info && child_proc_info->type == PROC_EXEC)
1188 debug_printf ("subproc_ready %p", child_proc_info->subproc_ready);
1189 if (!SetEvent (child_proc_info->subproc_ready))
1190 system_printf ("SetEvent (subproc_ready) failed, %E");
1191 ForceCloseHandle (child_proc_info->subproc_ready);
1194 SetEvent (wait_sig_inited);
1195 sigtid = GetCurrentThreadId ();
1197 /* If we got something like a SIGINT while we were initializing, the
1198 signal thread should be waiting for this event. This signals the
1199 thread that it's ok to send the signal since the wait_sig thread
1201 extern HANDLE console_handler_thread_waiter;
1202 SetEvent (console_handler_thread_waiter);
1204 HANDLE catchem[] = {sigcatch_main, sigcatch_nonmain, sigcatch_nosync};
1205 sigproc_printf ("Ready. dwProcessid %d", myself->dwProcessId);
1208 DWORD rc = WaitForMultipleObjects (3, catchem, FALSE, sig_loop_wait);
1210 /* sigproc_terminate sets sig_loop_wait to zero to indicate that
1211 * this thread should terminate.
1213 if (rc == WAIT_TIMEOUT)
1219 if (rc == WAIT_FAILED)
1221 if (sig_loop_wait != 0)
1222 system_printf ("WFMO failed, %E");
1226 rc -= WAIT_OBJECT_0;
1227 int dispatched = FALSE;
1228 sip_printf ("awake");
1229 /* A sigcatch semaphore has been signaled. Scan the sigtodo
1230 * array looking for any unprocessed signals.
1232 pending_signals = 0;
1233 int saw_sigchld = 0;
1234 int dispatched_sigchld = 0;
1235 for (int sig = -__SIGOFFSET; sig < NSIG; sig++)
1237 while (InterlockedDecrement (myself->getsigtodo(sig)) >= 0)
1241 if (sig > 0 && sig != SIGCONT && sig != SIGKILL && sig != SIGSTOP &&
1242 (sigismember (& myself->getsigmask (), sig) ||
1243 myself->process_state & PID_STOPPED))
1245 sip_printf ("sig %d blocked", sig);
1249 /* Found a signal to process */
1250 sip_printf ("processing signal %d", sig);
1254 /* just forcing the loop */
1257 /* Internal signal to force a flush of strace data to disk. */
1259 // proc_strace (); // Dump cached strace.prntf stuff.
1262 /* Signalled from a child process that it has stopped */
1263 case __SIGCHILDSTOPPED:
1264 sip_printf ("Received child stopped notification");
1265 dispatched |= sig_handle (SIGCHLD, rc);
1266 if (proc_subproc (PROC_CHILDSTOPPED, 0))
1270 /* A normal UNIX signal */
1272 sip_printf ("Got signal %d", sig);
1273 int wasdispatched = sig_handle (sig, rc);
1274 dispatched |= wasdispatched;
1275 if (sig == SIGCHLD && wasdispatched)
1276 dispatched_sigchld = 1;
1280 /* Decremented too far. */
1281 if (InterlockedIncrement (myself->getsigtodo(sig)) > 0)
1282 pending_signals = 1;
1287 if (saw_sigchld && !dispatched_sigchld)
1288 proc_subproc (PROC_CLEARWAIT, 0);
1289 /* Signal completion of signal handling depending on which semaphore
1290 * woke up the WaitForMultipleObjects above.
1295 SetEvent (sigcomplete_main);
1296 sigproc_printf ("signalled sigcomplete_main %p", sigcomplete_main);
1299 ReleaseSemaphore (sigcomplete_nonmain, 1, NULL);
1300 sigproc_printf ("signalled sigcomplete_nonmain %p", sigcomplete_nonmain);
1303 sigproc_printf ("Did not signal anyone");
1304 /* Signal from another process. No need to synchronize. */
1309 pending_signals = 1;
1310 sip_printf ("looping");
1313 sip_printf ("done");
1317 /* Wait for subprocesses to terminate. Executes in a separate thread. */
1319 wait_subproc (VOID *)
1321 sip_printf ("starting");
1326 DWORD rc = WaitForMultipleObjects (nchildren + 1, events, FALSE,
1328 if (rc == WAIT_TIMEOUT)
1329 if (!proc_loop_wait)
1334 if (rc == WAIT_FAILED)
1336 if (!proc_loop_wait)
1339 /* It's ok to get an ERROR_INVALID_HANDLE since another thread may have
1340 closed a handle in the children[] array. So, we try looping a couple
1341 of times to stabilize. FIXME - this is not foolproof. Probably, this
1342 thread should be responsible for closing the children. */
1343 if (++errloop < 10 && GetLastError () == ERROR_INVALID_HANDLE)
1346 system_printf ("wait failed. nchildren %d, wait %d, %E",
1347 nchildren, proc_loop_wait);
1349 for (int i = 0; i < nchildren + 1; i++)
1350 if ((rc = WaitForSingleObject (events[i], 0)) == WAIT_OBJECT_0 ||
1354 system_printf ("event[%d] %p, %E", i, events[0]);
1359 rc -= WAIT_OBJECT_0;
1361 (void)proc_subproc (PROC_CHILDTERMINATED, rc);
1362 sip_printf ("looping");
1365 ForceCloseHandle (events[0]);
1367 sip_printf ("done");