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
20 extern BOOL allow_ntsec;
25 #define WSSC 60000 // Wait for signal completion
26 #define WPSP 40000 // Wait for proc_subproc mutex
27 #define WSPX 20000 // Wait for wait_sig to terminate
28 #define WWSP 20000 // Wait for wait_subproc to terminate
30 #define WAIT_SIG_PRIORITY THREAD_PRIORITY_NORMAL
32 #define TOTSIGS (NSIG + __SIGOFFSET)
34 #define wake_wait_subproc() SetEvent (events[0])
36 #define no_signals_available() (!hwait_sig || !sig_loop_wait)
44 char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes to
45 // current process but no wait is required
46 char NO_COPY myself_nowait_nonmain_dummy[1] = {'1'};// Flag to sig_send that signal goes to
47 // current process but no wait is required
48 // if this is not the main thread.
50 HANDLE NO_COPY signal_arrived; // Event signaled when a signal has
51 // resulted in a user-specified
58 /* How long to wait for message/signals. Normally this is infinite.
59 * On termination, however, these are set to zero as a flag to exit.
62 #define Static static NO_COPY
64 Static DWORD proc_loop_wait = 500; // Wait for subprocesses to exit
65 Static DWORD sig_loop_wait = 500; // Wait for signals to arrive
67 Static HANDLE sigcatch_nonmain = NULL; // The semaphore signaled when
68 // signals are available for
69 // processing from non-main thread
70 Static HANDLE sigcatch_main = NULL; // Signalled when main thread sends a
72 Static HANDLE sigcatch_nosync = NULL; // Signal wait_sig to scan sigtodo
73 // but not to bother with any
75 Static HANDLE sigcomplete_main = NULL; // Event signaled when a signal has
76 // finished processing for the main
78 Static HANDLE sigcomplete_nonmain = NULL;// Semaphore raised for non-main
79 // threads when a signal has finished
81 Static HANDLE hwait_sig = NULL; // Handle of wait_sig thread
82 Static HANDLE hwait_subproc = NULL; // Handle of sig_subproc thread
84 Static HANDLE wait_sig_inited = NULL; // Control synchronization of
85 // message queue startup
87 /* Used by WaitForMultipleObjects. These are handles to child processes.
89 Static HANDLE events[PSIZE + 1] = {0}; // All my children's handles++
90 #define hchildren (events + 1) // Where the children handles begin
91 Static pinfo pchildren[PSIZE] = {pinfo ()};// All my children info
92 Static pinfo zombies[PSIZE] = {pinfo ()}; // All my deceased children info
93 Static int nchildren = 0; // Number of active children
94 Static int nzombies = 0; // Number of deceased children
96 Static waitq waitq_head = {0, 0, 0, 0, 0, 0, 0};// Start of queue for wait'ing threads
97 Static waitq waitq_main; // Storage for main thread
99 muto NO_COPY *sync_proc_subproc = NULL; // Control access to subproc stuff
101 DWORD NO_COPY sigtid = 0; // ID of the signal thread
103 int NO_COPY pending_signals = 0; // TRUE if signals pending
107 static int __stdcall checkstate (waitq *);
108 static __inline__ BOOL get_proc_lock (DWORD, DWORD);
109 static HANDLE __stdcall getsem (_pinfo *, const char *, int, int);
110 static void __stdcall remove_child (int);
111 static void __stdcall remove_zombie (int);
112 static DWORD WINAPI wait_sig (VOID *arg);
113 static int __stdcall stopped_or_terminated (waitq *, _pinfo *);
114 static DWORD WINAPI wait_subproc (VOID *);
116 /* Determine if the parent process is alive.
120 my_parent_is_alive ()
125 debug_printf ("No parent_alive mutex");
129 for (int i = 0; i < 2; i++)
130 switch (res = WaitForSingleObject (parent_alive, 0))
133 debug_printf ("parent dead.");
137 debug_printf ("parent still alive");
141 DWORD werr = GetLastError ();
142 if (werr == ERROR_INVALID_HANDLE && i == 0)
144 system_printf ("WFSO for parent_alive(%p) failed, error %d",
156 /* See if this is the first signal call after initialization.
157 * If so, wait for notification that all initialization has completed.
158 * Then set the handle to NULL to avoid checking this again.
162 (void) WaitForSingleObject (wait_sig_inited, INFINITE);
163 (void) ForceCloseHandle (wait_sig_inited);
164 wait_sig_inited = NULL;
168 static BOOL __stdcall
169 proc_can_be_signalled (_pinfo *p)
171 if (p == myself_nowait || p == myself_nowait_nonmain || p == myself)
177 return ISSTATE (p, PID_INITIALIZING) ||
178 (((p)->process_state & (PID_ACTIVE | PID_IN_USE)) ==
179 (PID_ACTIVE | PID_IN_USE));
183 proc_exists (pid_t pid)
186 return proc_exists (p);
189 /* Test to determine if a process really exists and is processing
193 proc_exists (_pinfo *p)
200 if (p == myself || p == myself_nowait_nonmain || p == myself_nowait)
203 if (p->process_state == PID_NOT_IN_USE || !p->dwProcessId)
206 sigproc_printf ("checking for existence of pid %d, window pid %d", p->pid,
208 if (p->ppid == myself->pid && p->hProcess != NULL)
210 sigproc_printf ("it's mine, process_state %x", p->process_state);
211 return proc_can_be_signalled (p);
214 /* Note: Process is alive if OpenProcess() call fails due to permissions */
215 if (((h = OpenProcess (STANDARD_RIGHTS_REQUIRED, FALSE, p->dwProcessId))
216 != NULL) || (GetLastError () == ERROR_ACCESS_DENIED))
218 sigproc_printf ("it exists, %p", h);
221 DWORD rc = WaitForSingleObject (h, 0);
223 if (rc == WAIT_OBJECT_0)
226 return proc_can_be_signalled (p);
229 sigproc_printf ("it doesn't exist");
230 /* If the parent pid does not exist, clean this process out of the pinfo
231 * table. It must have died abnormally.
233 if ((p->pid == p->ppid) || (p->ppid == 1) || !proc_exists (p->ppid))
236 p->process_state = PID_NOT_IN_USE;
241 /* Handle all subprocess requests
243 #define vchild (*((pinfo *) val))
245 proc_subproc (DWORD what, DWORD val)
254 #define wval ((waitq *) val)
256 sigproc_printf ("args: %x, %d", what, val);
258 if (!get_proc_lock (what, val)) // Serialize access to this function
260 sigproc_printf ("I am not ready");
266 /* Add a new subprocess to the children arrays.
267 * (usually called from the main thread)
270 if (nchildren >= PSIZE - 1)
271 system_printf ("nchildren too large %d", nchildren);
272 if (WaitForSingleObject (vchild->hProcess, 0) != WAIT_TIMEOUT)
274 system_printf ("invalid process handle %p. pid %d, win pid %d",
275 vchild->hProcess, vchild->pid, vchild->dwProcessId);
280 pchildren[nchildren] = vchild;
281 hchildren[nchildren] = vchild->hProcess;
282 ProtectHandle1 (vchild->hProcess, childhProc);
283 sigproc_printf ("added pid %d to wait list, slot %d, winpid %p, handle %p",
284 vchild->pid, nchildren, vchild->dwProcessId,
288 wake_wait_subproc ();
291 /* A child process had terminated.
292 * Possibly this is just due to an exec(). Cygwin implements an exec()
293 * as a "handoff" from one windows process to another. If child->hProcess
294 * is different from what is recorded in hchildren, then this is an exec().
295 * Otherwise this is a normal child termination event.
296 * (called from wait_subproc thread)
298 case PROC_CHILDTERMINATED:
300 if (GetExitCodeProcess (hchildren[val], &exitcode) &&
301 hchildren[val] != pchildren[val]->hProcess)
303 sigproc_printf ("pid %d[%d], reparented old hProcess %p, new %p",
304 pchildren[val]->pid, val, hchildren[val], pchildren[val]->hProcess);
305 ForceCloseHandle1 (hchildren[val], childhProc);
306 hchildren[val] = pchildren[val]->hProcess; /* Filled out by child */
307 ProtectHandle1 (pchildren[val]->hProcess, childhProc);
308 break; // This was an exec()
311 sigproc_printf ("pid %d[%d] terminated, handle %p, nchildren %d, nzombies %d",
312 pchildren[val]->pid, val, hchildren[val], nchildren, nzombies);
313 zombies[nzombies] = pchildren[val]; // Add to zombie array
314 zombies[nzombies++]->process_state = PID_ZOMBIE;// Walking dead
315 remove_child (val); // Remove from children array
316 if (!proc_loop_wait) // Don't bother if wait_subproc is
319 /* Send a SIGCHLD to myself. */
320 rc = sig_send (myself_nowait, SIGCHLD); // Send a SIGCHLD
323 /* A child is in the stopped state. Scan wait() queue to see if anyone
324 * should be notified. (Called from wait_sig thread)
326 case PROC_CHILDSTOPPED:
327 child = myself; // Just to avoid accidental NULL dereference
328 sigproc_printf ("Received stopped notification");
332 /* Clear all waiting threads. Called from exceptions.cc prior to
333 * the main thread's dispatch to a signal handler function.
334 * (called from wait_sig thread)
337 /* Clear all "wait"ing threads. */
339 sigproc_printf ("clear waiting threads");
341 sigproc_printf ("looking for processes to reap");
345 /* Scan the linked list of wait()ing threads. If a wait's parameters
346 * match this pid, then activate it.
348 for (w = &waitq_head; w->next != NULL; w = w->next)
350 if ((potential_match = checkstate (w)) > 0)
351 sigproc_printf ("released waiting thread");
352 else if (!clearing && potential_match < 0)
353 sigproc_printf ("only found non-terminated children");
354 else if (potential_match <= 0) // nothing matched
356 sigproc_printf ("waiting thread found no children");
357 HANDLE oldw = w->next->ev;
359 w->next->status = -1; /* flag that a signal was received */
362 if (!SetEvent (oldw))
363 system_printf ("couldn't wake up wait event %p, %E", oldw);
364 w->next = w->next->next;
371 sigproc_printf ("finished processing terminated/stopped child");
374 waitq_head.next = NULL;
375 sigproc_printf ("finished clearing");
379 /* Handle a wait4() operation. Allocates an event for the calling
380 * thread which is signaled when the appropriate pid exits or stops.
381 * (usually called from the main thread)
384 wval->ev = NULL; // Don't know event flag yet
387 child = NULL; // Not looking for a specific pid
388 else if (!proc_exists (wval->pid)) /* CGF FIXME -- test that this is one of mine */
389 goto out; // invalid pid. flag no such child
391 wval->status = 0; // Don't know status yet
393 /* Put waitq structure at the end of a linked list. */
394 for (w = &waitq_head; w->next != NULL; w = w->next)
395 if (w->next == wval && (w->next = w->next->next) == NULL)
398 wval->next = NULL; /* This will be last in the list */
399 sigproc_printf ("wval->pid %d, wval->options %d", wval->pid, wval->options);
401 /* If the first time for this thread, create a new event, otherwise
404 if ((wval->ev = wval->thread_ev) == NULL)
406 wval->ev = wval->thread_ev = CreateEvent (&sec_none_nih, TRUE,
408 ProtectHandle (wval->ev);
410 ResetEvent (wval->ev);
412 /* Scan list of children to see if any have died.
413 * If so, the event flag is set so that the wait* ()
414 * process will return immediately.
416 * If no children were found and the wait option was WNOHANG,
417 * then set the pid to 0 and remove the waitq value from
420 w->next = wval; /* set at end of wait queue */
421 if ((potential_match = checkstate (w)) <= 0)
423 if (!potential_match)
425 w->next = NULL; // don't want to keep looking
426 wval->ev = NULL; // flag that there are no children
427 sigproc_printf ("no appropriate children, %p, %p",
428 wval->thread_ev, wval->ev);
430 else if (wval->options & WNOHANG)
432 w->next = NULL; // don't want to keep looking
433 wval->pid = 0; // didn't find a pid
434 if (!SetEvent (wval->ev)) // wake up wait4 () immediately
435 system_printf ("Couldn't wake up wait event, %E");
436 sigproc_printf ("WNOHANG and no terminated children, %p, %p",
437 wval->thread_ev, wval->ev);
441 sigproc_printf ("wait activated %p, %p", wval->thread_ev, wval->ev);
442 else if (wval->ev != NULL)
443 sigproc_printf ("wait activated %p. Reaped zombie.", wval->ev);
445 sigproc_printf ("wait not activated %p, %p", wval->thread_ev, wval->ev);
450 sync_proc_subproc->release (); // Release the lock
452 sigproc_printf ("returning %d", rc);
456 /* Terminate the wait_subproc thread.
457 * Called on process exit.
458 * Also called by spawn_guts to disassociate any subprocesses from this
459 * process. Subprocesses will then know to clean up after themselves and
460 * will not become zombies.
463 proc_terminate (void)
465 sigproc_printf ("nchildren %d, nzombies %d", nchildren, nzombies);
466 /* Signal processing is assumed to be blocked in this routine. */
470 proc_loop_wait = 0; // Tell wait_subproc thread to exit
471 wake_wait_subproc (); // Wake wait_subproc loop
473 /* Wait for wait_subproc thread to exit (but not *too* long) */
474 if ((rc = WaitForSingleObject (hwait_subproc, WWSP)) != WAIT_OBJECT_0)
475 if (rc == WAIT_TIMEOUT)
476 system_printf ("WFSO(hwait_subproc) timed out");
478 system_printf ("WFSO(hwait_subproc), rc %d, %E", rc);
480 HANDLE h = hwait_subproc;
481 hwait_subproc = NULL;
482 ForceCloseHandle1 (h, hwait_subproc);
484 sync_proc_subproc->acquire(WPSP);
485 (void) proc_subproc (PROC_CLEARWAIT, 1);
487 /* Clean out zombie processes from the pid list. */
489 for (i = 0; i < nzombies; i++)
491 if (zombies[i]->hProcess)
493 ForceCloseHandle1 (zombies[i]->hProcess, childhProc);
494 zombies[i]->hProcess = NULL;
496 zombies[i]->process_state = PID_NOT_IN_USE; /* CGF FIXME - still needed? */
497 zombies[i].release();
500 /* Disassociate my subprocesses */
501 for (i = 0; i < nchildren; i++)
503 pinfo child; /* CGF FIXME */
504 if (pchildren[i]->process_state == PID_NOT_IN_USE)
505 continue; // Should never happen
506 if (!pchildren[i]->hProcess)
507 sigproc_printf ("%d(%d) hProcess cleared already?", pchildren[i]->pid,
508 pchildren[i]->dwProcessId);
511 ForceCloseHandle1 (pchildren[i]->hProcess, childhProc);
512 pchildren[i]->hProcess = NULL;
513 if (!proc_exists (pchildren[i]))
515 sigproc_printf ("%d(%d) doesn't exist", pchildren[i]->pid,
516 pchildren[i]->dwProcessId);
517 pchildren[i]->process_state = PID_NOT_IN_USE; /* a reaped child CGF FIXME -- still needed? */
521 sigproc_printf ("%d(%d) closing active child handle", pchildren[i]->pid,
522 pchildren[i]->dwProcessId);
523 pchildren[i]->ppid = 1;
524 if (pchildren[i]->pgid == myself->pid)
525 pchildren[i]->process_state |= PID_ORPHANED;
528 pchildren[i].release ();
530 nchildren = nzombies = 0;
532 /* Attempt to close and release sync_proc_subproc in a
533 * non-raceable manner.
535 muto *m = sync_proc_subproc;
538 sync_proc_subproc = NULL;
542 sigproc_printf ("leaving");
545 /* Clear pending signal from the sigtodo array
550 (void) InterlockedExchange (myself->getsigtodo(sig), 0L);
554 /* Force the wait_sig thread to wake up and scan the sigtodo array.
556 extern "C" int __stdcall
557 sig_dispatch_pending (int justwake)
562 int was_pending = pending_signals;
564 sigproc_printf ("pending_signals %d", was_pending);
566 if (!was_pending && !justwake)
568 sigproc_printf ("no need to wake anything up");
576 (void) sig_send (myself, __SIGFLUSH);
577 else if (ReleaseSemaphore (sigcatch_nosync, 1, NULL))
579 sigproc_printf ("woke up wait_sig");
583 else if (no_signals_available ())
584 /*sigproc_printf ("I'm going away now")*/;
586 system_printf ("%E releasing sigcatch_nosync(%p)", sigcatch_nosync);
592 /* Message initialization. Called from dll_crt0_1
594 * This routine starts the signal handling thread. The wait_sig_inited
595 * event is used to signal that the thread is ready to handle signals.
596 * We don't wait for this during initialization but instead detect it
597 * in sig_send to gain a little concurrency.
602 wait_sig_inited = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
603 ProtectHandle (wait_sig_inited);
605 /* local event signaled when main thread has been dispatched
606 to a signal handler function. */
607 signal_arrived = CreateEvent(&sec_none_nih, TRUE, FALSE, NULL);
609 if (!(hwait_sig = makethread (wait_sig, NULL, 0, "sig")))
611 system_printf ("cannot create wait_sig thread, %E");
612 api_fatal ("terminating");
615 ProtectHandle (hwait_sig);
617 /* sync_proc_subproc is used by proc_subproc. It serialises
618 * access to the children and zombie arrays.
620 sync_proc_subproc = new_muto (FALSE, "sync_proc_subproc");
622 /* Initialize waitq structure for main thread. A waitq structure is
623 * allocated for each thread that executes a wait to allow multiple threads
624 * to perform waits. Pre-allocate a waitq structure for the main thread.
627 if ((w = (waitq *)waitq_storage.get ()) == NULL)
630 waitq_storage.set (w);
632 memset (w, 0, sizeof *w); // Just to be safe
634 sigproc_printf ("process/signal handling enabled(%x)", myself->process_state);
638 /* Called on process termination to terminate signal and process threads.
641 sigproc_terminate (void)
643 HANDLE h = hwait_sig;
646 if (GetCurrentThreadId () == sigtid)
648 ForceCloseHandle (sigcomplete_main);
649 for (int i = 0; i < 20; i++)
650 (void) ReleaseSemaphore (sigcomplete_nonmain, 1, NULL);
651 ForceCloseHandle (sigcomplete_nonmain);
652 ForceCloseHandle (sigcatch_main);
653 ForceCloseHandle (sigcatch_nonmain);
654 ForceCloseHandle (sigcatch_nosync);
656 proc_terminate (); // Terminate process handling thread
659 sigproc_printf ("sigproc_terminate: sigproc handling not active");
662 sigproc_printf ("entering");
663 sig_loop_wait = 0; // Tell wait_sig to exit when it is
664 // finished with anything it is doing
665 sig_dispatch_pending (TRUE); // wake up and die
667 /* If !hwait_sig, then the process probably hasn't even finished
668 * its initialization phase.
672 if (GetCurrentThreadId () != sigtid)
673 WaitForSingleObject (h, 10000);
674 ForceCloseHandle1 (h, hwait_sig);
676 /* Exiting thread. Cleanup. Don't set to inactive if a child has been
677 execed with the same pid. */
678 if (!myself->dwProcessId || myself->dwProcessId == GetCurrentProcessId ())
679 myself->process_state &= ~PID_ACTIVE;
681 sigproc_printf ("Did not clear PID_ACTIVE since %d != %d",
682 myself->dwProcessId, GetCurrentProcessId ());
684 /* In case of a sigsuspend */
685 SetEvent (signal_arrived);
687 if (GetCurrentThreadId () != sigtid)
689 ForceCloseHandle (sigcomplete_main);
690 ForceCloseHandle (sigcomplete_nonmain);
691 ForceCloseHandle (sigcatch_main);
692 ForceCloseHandle (sigcatch_nonmain);
693 ForceCloseHandle (sigcatch_nosync);
696 sigproc_printf ("done");
699 /* Set this so that subsequent tests will succeed. */
700 if (!myself->dwProcessId)
701 myself->dwProcessId = GetCurrentProcessId ();
706 /* Send a signal to another process by raising its signal semaphore.
707 * If pinfo *p == NULL, send to the current process.
708 * If sending to this process, wait for notification that a signal has
709 * completed before returning.
712 sig_send (_pinfo *p, int sig, DWORD ebp)
715 DWORD tid = GetCurrentThreadId ();
717 HANDLE thiscatch = NULL;
718 HANDLE thiscomplete = NULL;
719 BOOL wait_for_completion;
722 if (p == myself_nowait_nonmain)
723 p = (tid == mainthread.id) ? (_pinfo *) myself : myself_nowait;
724 if (!(its_me = (p == NULL || p == myself || p == myself_nowait)))
725 wait_for_completion = FALSE;
728 if (no_signals_available ())
729 goto out; // Either exiting or not yet initializing
731 wait_for_completion = p != myself_nowait;
735 /* It is possible that the process is not yet ready to receive messages
736 * or that it has exited. Detect this.
738 if (!proc_can_be_signalled (p)) /* Is the process accepting messages? */
740 sigproc_printf ("invalid pid %d(%x), signal %d",
741 p->pid, p->process_state, sig);
746 sigproc_printf ("pid %d, signal %d, its_me %d", p->pid, sig, its_me);
750 if (!wait_for_completion)
751 thiscatch = sigcatch_nosync;
752 else if (tid != mainthread.id)
754 thiscatch = sigcatch_nonmain;
755 thiscomplete = sigcomplete_nonmain;
759 thiscatch = sigcatch_main;
760 thiscomplete = sigcomplete_main;
761 thisframe.set (mainthread, 1, ebp);
764 else if (!(thiscatch = getsem (p, "sigcatch", 0, 0)))
765 goto out; // Couldn't get the semaphore. getsem issued
766 // an error, if appropriate.
768 #if WHEN_MULTI_THREAD_SIGNALS_WORK
770 sd = signal_dispatch_storage.get ();
772 sd = signal_dispatch_storage.create ();
775 /* Increment the sigtodo array to signify which signal to assert.
777 (void) InterlockedIncrement (p->getsigtodo(sig));
779 /* Notify the process that a signal has arrived.
785 prio = GetThreadPriority (GetCurrentThread ());
786 (void) SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
789 if (!ReleaseSemaphore (thiscatch, 1, NULL) && (int) GetLastError () > 0)
791 sigproc_printf ("ReleaseSemaphore failed, %E");
792 /* Couldn't signal the semaphore. This probably means that the
793 * process is exiting.
796 ForceCloseHandle (thiscatch);
799 if (no_signals_available ())
800 sigproc_printf ("I'm going away now");
801 else if ((int) GetLastError () == -1)
802 rc = WaitForSingleObject (thiscomplete, 500);
804 system_printf ("error sending signal %d to pid %d, semaphore %p, %E",
805 sig, p->pid, thiscatch);
809 sigproc_printf ("ReleaseSemaphore succeeded");
811 /* No need to wait for signal completion unless this was a signal to
814 * If it was a signal to this process, wait for a dispatched signal.
815 * Otherwise just wait for the wait_sig to signal that it has finished
816 * processing the signal.
818 if (!wait_for_completion)
821 sigproc_printf ("Not waiting for sigcomplete. its_me %d sig %d", its_me, sig);
823 ForceCloseHandle (thiscatch);
827 sigproc_printf ("Waiting for thiscomplete %p", thiscomplete);
830 rc = WaitForSingleObject (thiscomplete, WSSC);
831 /* Check for strangeness due to this thread being redirected by the
832 signal handler. Sometimes a WAIT_TIMEOUT will occur when the
833 thread hasn't really timed out. So, check again.
834 FIXME: This isn't foolproof. */
835 if (rc != WAIT_OBJECT_0 &&
836 WaitForSingleObject (thiscomplete, 0) == WAIT_OBJECT_0)
841 SetThreadPriority (GetCurrentThread (), prio);
844 if (rc == WAIT_OBJECT_0)
845 rc = 0; // Successful exit
848 /* It's an error unless sig_loop_wait == 0 (the process is exiting). */
849 if (!no_signals_available ())
850 system_printf ("wait for sig_complete event failed, sig %d, rc %d, %E",
857 sigproc_printf ("returning %d from sending signal %d", rc, sig);
861 /* Set pending signal from the sigtodo array
864 sig_set_pending (int sig)
866 (void) InterlockedIncrement (myself->getsigtodo(sig));
870 /* Initialize the wait_subproc thread.
871 * Called from fork() or spawn() to initialize the handling of subprocesses.
879 /* A "wakeup" handle which can be toggled to make wait_subproc reexamine
880 * the hchildren array.
882 events[0] = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
883 if (!(hwait_subproc = makethread (wait_subproc, NULL, 0, "+proc")))
884 system_printf ("cannot create wait_subproc thread, %E");
885 ProtectHandle (events[0]);
886 ProtectHandle (hwait_subproc);
887 sigproc_printf ("started wait_subproc thread %p", hwait_subproc);
890 /* Initialize some of the memory block passed to child processes
891 by fork/spawn/exec. */
894 init_child_info (DWORD chtype, child_info *ch, pid_t pid, HANDLE subproc_ready)
897 memset (ch, 0, sizeof *ch);
901 ch->shared_h = cygwin_shared_h;
902 ch->console_h = console_shared_h;
903 ch->subproc_ready = subproc_ready;
904 if (chtype != PROC_EXEC || !parent_alive)
905 ch->parent_alive = hwait_subproc;
906 else if (parent_alive)
907 DuplicateHandle (hMainProc, parent_alive, hMainProc, &ch->parent_alive,
908 0, 1, DUPLICATE_SAME_ACCESS);
911 /* Check the state of all of our children to see if any are stopped or
915 checkstate (waitq *w)
917 int i, x, potential_match = 0;
920 sigproc_printf ("nchildren %d, nzombies %d", nchildren, nzombies);
922 /* Check already dead processes first to see if they match the criteria
925 for (i = 0; i < nzombies; i++)
926 if ((x = stopped_or_terminated (w, child = zombies[i])) < 0)
927 potential_match = -1;
935 sigproc_printf ("checking alive children");
937 /* No dead terminated children matched. Check for stopped children. */
938 for (i = 0; i < nchildren; i++)
939 if ((x = stopped_or_terminated (w, pchildren[i])) < 0)
940 potential_match = -1;
948 sigproc_printf ("returning %d", potential_match);
949 return potential_match;
952 /* Get or create a process specific semaphore used in message passing.
954 static HANDLE __stdcall
955 getsem (_pinfo *p, const char *str, int init, int max)
961 if (!proc_can_be_signalled (p))
967 sigproc_printf ("pid %d, ppid %d, wait %d, initializing %x", p->pid, p->ppid, wait,
968 ISSTATE (p, PID_INITIALIZING));
969 for (int i = 0; ISSTATE (p, PID_INITIALIZING) && i < wait; i++)
978 DWORD winpid = GetCurrentProcessId ();
979 h = CreateSemaphore (allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
980 init, max, str = shared_name (str, winpid));
985 h = OpenSemaphore (SEMAPHORE_ALL_ACCESS, FALSE,
986 str = shared_name (str, p->dwProcessId));
990 if (GetLastError () == ERROR_FILE_NOT_FOUND && !proc_exists (p))
1000 system_printf ("can't %s %s, %E", p ? "open" : "create", str);
1006 /* Get the sync_proc_subproc muto to control access to
1007 * children, zombie arrays.
1008 * Attempt to handle case where process is exiting as we try to grab
1012 get_proc_lock (DWORD what, DWORD val)
1014 Static int lastwhat = -1;
1015 if (!sync_proc_subproc)
1017 if (sync_proc_subproc->acquire (WPSP))
1022 if (!sync_proc_subproc)
1024 system_printf ("Couldn't aquire sync_proc_subproc for(%d,%d), %E, last %d",
1025 what, val, lastwhat);
1029 /* Remove a child from pchildren/hchildren by swapping it with the
1030 * last child in the list.
1032 static void __stdcall
1033 remove_child (int ci)
1035 sigproc_printf ("removing [%d], pid %d, handle %p, nchildren %d",
1036 ci, pchildren[ci]->pid, hchildren[ci], nchildren);
1037 if (ci < --nchildren)
1039 pchildren[ci] = pchildren[nchildren];
1040 hchildren[ci] = hchildren[nchildren];
1046 /* Remove a zombie from zombies by swapping it with the last child in the list.
1048 static void __stdcall
1049 remove_zombie (int ci)
1051 sigproc_printf ("removing %d, pid %d, nzombies %d", ci, zombies[ci]->pid,
1055 zombies[ci].release ();
1057 if (ci < --nzombies)
1058 zombies[ci] = zombies[nzombies];
1063 /* Check status of child process vs. waitq member.
1065 * parent_w is the pointer to the parent of the waitq member in question.
1066 * child is the subprocess being considered.
1069 * 1 if stopped or terminated child matches parent_w->next criteria
1070 * -1 if a non-stopped/terminated child matches parent_w->next criteria
1071 * 0 if child does not match parent_w->next criteria
1073 static int __stdcall
1074 stopped_or_terminated (waitq *parent_w, _pinfo *child)
1076 int potential_match;
1077 waitq *w = parent_w->next;
1079 sigproc_printf ("considering pid %d", child->pid);
1081 potential_match = 1;
1082 else if (w->pid == 0)
1083 potential_match = child->pgid == myself->pgid;
1084 else if (w->pid < 0)
1085 potential_match = child->pgid == -w->pid;
1087 potential_match = (w->pid == child->pid);
1089 if (!potential_match)
1094 if ((terminated = child->process_state == PID_ZOMBIE) ||
1095 (w->options & WUNTRACED) && child->stopsig)
1097 parent_w->next = w->next; /* successful wait. remove from wait queue */
1098 w->pid = child->pid;
1102 sigproc_printf ("stopped child");
1103 w->status = (child->stopsig << 8) | 0x7f;
1106 else /* Should only get here when child has been moved to the zombies array */
1109 if (!GetExitCodeProcess (child->hProcess, &status))
1111 if (status & EXIT_SIGNAL)
1112 w->status = (status >> 8) & 0xff; /* exited due to signal */
1114 w->status = (status & 0xff) << 8; /* exited via "exit ()" */
1116 add_rusage (&myself->rusage_children, &child->rusage_children);
1117 add_rusage (&myself->rusage_children, &child->rusage_self);
1121 add_rusage ((struct rusage *) w->rusage, &child->rusage_children);
1122 add_rusage ((struct rusage *) w->rusage, &child->rusage_self);
1124 ForceCloseHandle1 (child->hProcess, childhProc);
1125 child->hProcess = NULL;
1126 child->process_state = PID_NOT_IN_USE; /* a reaped child */
1129 if (!SetEvent (w->ev)) /* wake up wait4 () immediately */
1130 system_printf ("couldn't wake up wait event %p, %E", w->ev);
1134 return -potential_match;
1137 /* Process signals by waiting for a semaphore to become signaled.
1138 * Then scan an in-memory array representing queued signals.
1139 * Executes in a separate thread.
1141 * Signals sent from this process are sent a completion signal so
1142 * that returns from kill/raise do not occur until the signal has
1143 * has been handled, as per POSIX.
1148 /* Initialization */
1149 (void) SetThreadPriority (hwait_sig, WAIT_SIG_PRIORITY);
1151 /* sigcatch_nosync - semaphore incremented by sig_dispatch_pending and
1152 * by foreign processes to force an examination of
1153 * the sigtodo array.
1154 * sigcatch_main - ditto for local main thread.
1155 * sigcatch_nonmain - ditto for local non-main threads.
1157 * sigcomplete_main - event used to signal main thread on signal
1159 * sigcomplete_nonmain - semaphore signaled for non-main thread on signal
1162 sigcatch_nosync = getsem (NULL, "sigcatch", 0, MAXLONG);
1163 sigcatch_nonmain = CreateSemaphore (&sec_none_nih, 0, MAXLONG, NULL);
1164 sigcatch_main = CreateSemaphore (&sec_none_nih, 0, MAXLONG, NULL);
1165 sigcomplete_nonmain = CreateSemaphore (&sec_none_nih, 0, MAXLONG, NULL);
1166 sigcomplete_main = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
1167 sigproc_printf ("sigcatch_nonmain %p", sigcatch_nonmain);
1169 /* Setting dwProcessId flags that this process is now capable of receiving
1170 * signals. Prior to this, dwProcessId was set to the windows pid of
1171 * of the original windows process which spawned us unless this was a
1172 * "toplevel" process.
1174 myself->dwProcessId = GetCurrentProcessId ();
1175 myself->process_state |= PID_ACTIVE;
1176 myself->process_state &= ~PID_INITIALIZING;
1178 ProtectHandle (sigcatch_nosync);
1179 ProtectHandle (sigcatch_nonmain);
1180 ProtectHandle (sigcatch_main);
1181 ProtectHandle (sigcomplete_nonmain);
1182 ProtectHandle (sigcomplete_main);
1184 /* If we've been execed, then there is still a stub left in the previous
1185 * windows process waiting to see if it's started a cygwin process or not.
1186 * Signalling subproc_ready indicates that we are a cygwin process.
1188 if (child_proc_info && child_proc_info->type == PROC_EXEC)
1190 debug_printf ("subproc_ready %p", child_proc_info->subproc_ready);
1191 if (!SetEvent (child_proc_info->subproc_ready))
1192 system_printf ("SetEvent (subproc_ready) failed, %E");
1193 ForceCloseHandle (child_proc_info->subproc_ready);
1196 SetEvent (wait_sig_inited);
1197 sigtid = GetCurrentThreadId ();
1199 /* If we got something like a SIGINT while we were initializing, the
1200 signal thread should be waiting for this event. This signals the
1201 thread that it's ok to send the signal since the wait_sig thread
1203 extern HANDLE console_handler_thread_waiter;
1204 SetEvent (console_handler_thread_waiter);
1206 HANDLE catchem[] = {sigcatch_main, sigcatch_nonmain, sigcatch_nosync};
1207 sigproc_printf ("Ready. dwProcessid %d", myself->dwProcessId);
1210 DWORD rc = WaitForMultipleObjects (3, catchem, FALSE, sig_loop_wait);
1212 /* sigproc_terminate sets sig_loop_wait to zero to indicate that
1213 * this thread should terminate.
1215 if (rc == WAIT_TIMEOUT)
1221 if (rc == WAIT_FAILED)
1223 if (sig_loop_wait != 0)
1224 system_printf ("WFMO failed, %E");
1228 rc -= WAIT_OBJECT_0;
1229 int dispatched = FALSE;
1230 sigproc_printf ("awake");
1231 /* A sigcatch semaphore has been signaled. Scan the sigtodo
1232 * array looking for any unprocessed signals.
1234 pending_signals = 0;
1235 int saw_sigchld = 0;
1236 int dispatched_sigchld = 0;
1237 for (int sig = -__SIGOFFSET; sig < NSIG; sig++)
1239 while (InterlockedDecrement (myself->getsigtodo(sig)) >= 0)
1243 if (sig > 0 && sig != SIGCONT && sig != SIGKILL && sig != SIGSTOP &&
1244 (sigismember (& myself->getsigmask (), sig) ||
1245 myself->process_state & PID_STOPPED))
1247 sigproc_printf ("sig %d blocked", sig);
1251 /* Found a signal to process */
1252 sigproc_printf ("processing signal %d", sig);
1256 /* just forcing the loop */
1259 /* Internal signal to force a flush of strace data to disk. */
1261 // proc_strace (); // Dump cached strace.prntf stuff.
1264 /* Signalled from a child process that it has stopped */
1265 case __SIGCHILDSTOPPED:
1266 sigproc_printf ("Received child stopped notification");
1267 dispatched |= sig_handle (SIGCHLD);
1268 if (proc_subproc (PROC_CHILDSTOPPED, 0))
1272 /* A normal UNIX signal */
1274 sigproc_printf ("Got signal %d", sig);
1275 int wasdispatched = sig_handle (sig);
1276 dispatched |= wasdispatched;
1277 if (sig == SIGCHLD && wasdispatched)
1278 dispatched_sigchld = 1;
1282 /* Decremented too far. */
1283 if (InterlockedIncrement (myself->getsigtodo(sig)) > 0)
1284 pending_signals = 1;
1289 if (saw_sigchld && !dispatched_sigchld)
1290 proc_subproc (PROC_CLEARWAIT, 0);
1291 /* Signal completion of signal handling depending on which semaphore
1292 * woke up the WaitForMultipleObjects above.
1297 SetEvent (sigcomplete_main);
1300 ReleaseSemaphore (sigcomplete_nonmain, 1, NULL);
1303 /* Signal from another process. No need to synchronize. */
1308 pending_signals = 1;
1309 sigproc_printf ("looping");
1312 sigproc_printf ("done");
1316 /* Wait for subprocesses to terminate. Executes in a separate thread. */
1318 wait_subproc (VOID *)
1320 sigproc_printf ("starting");
1325 DWORD rc = WaitForMultipleObjects (nchildren + 1, events, FALSE,
1327 if (rc == WAIT_TIMEOUT)
1328 if (!proc_loop_wait)
1333 if (rc == WAIT_FAILED)
1335 if (!proc_loop_wait)
1338 /* It's ok to get an ERROR_INVALID_HANDLE since another thread may have
1339 closed a handle in the children[] array. So, we try looping a couple
1340 of times to stabilize. FIXME - this is not foolproof. Probably, this
1341 thread should be responsible for closing the children. */
1342 if (++errloop < 10 && GetLastError () == ERROR_INVALID_HANDLE)
1345 system_printf ("wait failed. nchildren %d, wait %d, %E",
1346 nchildren, proc_loop_wait);
1348 for (int i = 0; i < nchildren + 1; i++)
1349 if ((rc = WaitForSingleObject (events[i], 0)) == WAIT_OBJECT_0 ||
1353 system_printf ("event[%d] %p, %E", i, events[0]);
1358 rc -= WAIT_OBJECT_0;
1360 (void)proc_subproc (PROC_CHILDTERMINATED, rc);
1361 sigproc_printf ("looping");
1364 ForceCloseHandle (events[0]);
1366 sigproc_printf ("done");
1371 /* Provide a stack frame when calling WaitFor* functions */
1373 #undef WaitForSingleObject
1376 WFSO (HANDLE hHandle, DWORD dwMilliseconds)
1379 sigframe thisframe (mainthread);
1380 ret = WaitForSingleObject (hHandle, dwMilliseconds);
1384 #undef WaitForMultipleObjects
1387 WFMO (DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds)
1390 sigframe thisframe (mainthread);
1391 ret = WaitForMultipleObjects (nCount, lpHandles, fWaitAll, dwMilliseconds);