OSDN Git Service

5e1a2edee31bd87c100962c40d69c270f65ad479
[pf3gnuchains/pf3gnuchains3x.git] / winsup / cygwin / sigproc.cc
1 /* sigproc.cc: inter/intra signal and sub process handler
2
3    Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
4
5    Written by Christopher Faylor
6
7 This file is part of Cygwin.
8
9 This software is a copyrighted work licensed under the terms of the
10 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
11 details. */
12
13 #include "winsup.h"
14 #include <stdlib.h>
15 #include <time.h>
16 #include <sys/wait.h>
17 #include <stdlib.h>
18 #include <sys/cygwin.h>
19 #include <assert.h>
20 #include <sys/signal.h>
21 #include "cygerrno.h"
22 #include "sync.h"
23 #include "pinfo.h"
24 #include "security.h"
25 #include "path.h"
26 #include "fhandler.h"
27 #include "dtable.h"
28 #include "cygheap.h"
29 #include "child_info_magic.h"
30 #include "shared_info.h"
31 #include "cygtls.h"
32 #include "sigproc.h"
33 #include "exceptions.h"
34
35 /*
36  * Convenience defines
37  */
38 #define WSSC              60000 // Wait for signal completion
39 #define WPSP              40000 // Wait for proc_subproc mutex
40
41 #define no_signals_available(x) (!my_sendsig || ((x) && myself->exitcode & EXITCODE_SET) || &_my_tls == _sig_tls)
42
43 #define NPROCS  256
44
45 /*
46  * Global variables
47  */
48 struct sigaction *global_sigs;
49
50 const char *__sp_fn ;
51 int __sp_ln;
52
53 char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes to
54                                         //  current process but no wait is required
55 HANDLE NO_COPY signal_arrived;          // Event signaled when a signal has
56                                         //  resulted in a user-specified
57                                         //  function call
58
59 #define Static static NO_COPY
60
61 HANDLE NO_COPY sigCONT;                 // Used to "STOP" a process
62
63 Static HANDLE wait_sig_inited;          // Control synchronization of
64                                         //  message queue startup
65
66 Static int nprocs;                      // Number of deceased children
67 Static char cprocs[(NPROCS + 1) * sizeof (pinfo)];// All my children info
68 #define procs ((pinfo *) cprocs)        // All this just to avoid expensive
69                                         // constructor operation  at DLL startup
70 Static waitq waitq_head = {0, 0, 0, 0, 0, 0, 0};// Start of queue for wait'ing threads
71
72 static muto NO_COPY sync_proc_subproc;  // Control access to subproc stuff
73
74 _cygtls NO_COPY *_sig_tls;
75
76 /* Function declarations */
77 static int __stdcall checkstate (waitq *) __attribute__ ((regparm (1)));
78 static __inline__ bool get_proc_lock (DWORD, DWORD);
79 static bool __stdcall remove_proc (int);
80 static bool __stdcall stopped_or_terminated (waitq *, _pinfo *);
81 static DWORD WINAPI wait_sig (VOID *arg);
82 static HANDLE NO_COPY my_sendsig;
83
84 /* wait_sig bookkeeping */
85
86 class pending_signals
87 {
88   sigpacket sigs[NSIG + 1];
89   sigpacket start;
90   sigpacket *end;
91   sigpacket *prev;
92   sigpacket *curr;
93 public:
94   void reset () {curr = &start; prev = &start;}
95   void add (sigpacket&);
96   void del ();
97   sigpacket *next ();
98   sigpacket *save () const {return curr;}
99   void restore (sigpacket *saved) {curr = saved;}
100   friend void __stdcall sig_dispatch_pending (bool);
101   friend DWORD WINAPI wait_sig (VOID *arg);
102 };
103
104 static pending_signals sigq;
105
106 /* Functions */
107 void __stdcall
108 sigalloc ()
109 {
110   cygheap->sigs = global_sigs =
111     (struct sigaction *) ccalloc (HEAP_SIGS, NSIG, sizeof (struct sigaction));
112 }
113
114 void __stdcall
115 signal_fixup_after_exec ()
116 {
117   global_sigs = cygheap->sigs;
118   /* Set up child's signal handlers */
119   for (int i = 0; i < NSIG; i++)
120     {
121       global_sigs[i].sa_mask = 0;
122       if (global_sigs[i].sa_handler != SIG_IGN)
123         {
124           global_sigs[i].sa_handler = SIG_DFL;
125           global_sigs[i].sa_flags &= ~ SA_SIGINFO;
126         }
127     }
128 }
129
130 void __stdcall
131 wait_for_sigthread ()
132 {
133   sigproc_printf ("wait_sig_inited %p", wait_sig_inited);
134   HANDLE hsig_inited = wait_sig_inited;
135   WaitForSingleObject (hsig_inited, INFINITE);
136   wait_sig_inited = NULL;
137   ForceCloseHandle1 (hsig_inited, wait_sig_inited);
138 }
139
140 /* Get the sync_proc_subproc muto to control access to
141  * children, proc arrays.
142  * Attempt to handle case where process is exiting as we try to grab
143  * the mutex.
144  */
145 static bool
146 get_proc_lock (DWORD what, DWORD val)
147 {
148   Static int lastwhat = -1;
149   if (!sync_proc_subproc)
150     {
151       sigproc_printf ("sync_proc_subproc is NULL (1)");
152       return false;
153     }
154   if (sync_proc_subproc.acquire (WPSP))
155     {
156       lastwhat = what;
157       return true;
158     }
159   if (!sync_proc_subproc)
160     {
161       sigproc_printf ("sync_proc_subproc is NULL (2)");
162       return false;
163     }
164   system_printf ("Couldn't aquire sync_proc_subproc for(%d,%d), last %d, %E",
165                   what, val, lastwhat);
166   return true;
167 }
168
169 static bool __stdcall
170 proc_can_be_signalled (_pinfo *p)
171 {
172   if (!(p->exitcode & EXITCODE_SET))
173     {
174       if (ISSTATE (p, PID_INITIALIZING) ||
175           (((p)->process_state & (PID_ACTIVE | PID_IN_USE)) ==
176            (PID_ACTIVE | PID_IN_USE)))
177         return true;
178     }
179
180   set_errno (ESRCH);
181   return false;
182 }
183
184 bool __stdcall
185 pid_exists (pid_t pid)
186 {
187   return pinfo (pid)->exists ();
188 }
189
190 /* Return true if this is one of our children, false otherwise.  */
191 static inline bool __stdcall
192 mychild (int pid)
193 {
194   for (int i = 0; i < nprocs; i++)
195     if (procs[i]->pid == pid)
196       return true;
197   return false;
198 }
199
200 /* Handle all subprocess requests
201  */
202 int __stdcall
203 proc_subproc (DWORD what, DWORD val)
204 {
205   int rc = 1;
206   int potential_match;
207   _pinfo *child;
208   int clearing;
209   waitq *w;
210
211 #define wval     ((waitq *) val)
212 #define vchild (*((pinfo *) val))
213
214   sigproc_printf ("args: %x, %d", what, val);
215
216   if (!get_proc_lock (what, val))       // Serialize access to this function
217     {
218       system_printf ("couldn't get proc lock. what %d, val %d", what, val);
219       goto out1;
220     }
221
222   switch (what)
223     {
224     /* Add a new subprocess to the children arrays.
225      * (usually called from the main thread)
226      */
227     case PROC_ADDCHILD:
228       /* Filled up process table? */
229       if (nprocs >= NPROCS)
230         {
231           sigproc_printf ("proc table overflow: hit %d processes, pid %d\n",
232                           nprocs, vchild->pid);
233           rc = 0;
234           set_errno (EAGAIN);
235           break;
236         }
237       /* fall through intentionally */
238
239     case PROC_DETACHED_CHILD:
240       if (vchild != myself)
241         {
242           vchild->ppid = what == PROC_DETACHED_CHILD ? 1 : myself->pid;
243           vchild->uid = myself->uid;
244           vchild->gid = myself->gid;
245           vchild->pgid = myself->pgid;
246           vchild->sid = myself->sid;
247           vchild->ctty = myself->ctty;
248           vchild->cygstarted = true;
249           vchild->process_state |= PID_INITIALIZING | (myself->process_state & PID_USETTY);
250         }
251       if (what == PROC_DETACHED_CHILD)
252         break;
253       procs[nprocs] = vchild;
254       rc = procs[nprocs].wait ();
255       if (rc)
256         {
257           sigproc_printf ("added pid %d to proc table, slot %d", vchild->pid,
258                           nprocs);
259           nprocs++;
260         }
261       break;
262
263     /* Handle a wait4() operation.  Allocates an event for the calling
264      * thread which is signaled when the appropriate pid exits or stops.
265      * (usually called from the main thread)
266      */
267     case PROC_WAIT:
268       wval->ev = NULL;          // Don't know event flag yet
269
270       if (wval->pid == -1 || !wval->pid)
271         child = NULL;           // Not looking for a specific pid
272       else if (!mychild (wval->pid))
273         goto out;               // invalid pid.  flag no such child
274
275       wval->status = 0;         // Don't know status yet
276       sigproc_printf ("wval->pid %d, wval->options %d", wval->pid, wval->options);
277
278       /* If the first time for this thread, create a new event, otherwise
279        * reset the event.
280        */
281       if ((wval->ev = wval->thread_ev) == NULL)
282         {
283           wval->ev = wval->thread_ev = CreateEvent (&sec_none_nih, TRUE, FALSE,
284                                                     NULL);
285           ProtectHandle1 (wval->ev, wq_ev);
286         }
287
288       ResetEvent (wval->ev);
289       w = waitq_head.next;
290       waitq_head.next = wval;   /* Add at the beginning. */
291       wval->next = w;           /* Link in rest of the list. */
292       clearing = 0;
293       goto scan_wait;
294
295     /* Clear all waiting threads.  Called from exceptions.cc prior to
296        the main thread's dispatch to a signal handler function.
297        (called from wait_sig thread) */
298     case PROC_CLEARWAIT:
299       /* Clear all "wait"ing threads. */
300       if (val)
301         sigproc_printf ("clear waiting threads");
302       else
303         sigproc_printf ("looking for processes to reap, nprocs %d", nprocs);
304       clearing = val;
305
306     scan_wait:
307       /* Scan the linked list of wait()ing threads.  If a wait's parameters
308          match this pid, then activate it.  */
309       for (w = &waitq_head; w->next != NULL; w = w->next)
310         {
311           if ((potential_match = checkstate (w)) > 0)
312             sigproc_printf ("released waiting thread");
313           else if (!clearing && !(w->next->options & WNOHANG) && potential_match < 0)
314             sigproc_printf ("only found non-terminated children");
315           else if (potential_match <= 0)                // nothing matched
316             {
317               sigproc_printf ("waiting thread found no children");
318               HANDLE oldw = w->next->ev;
319               w->next->pid = 0;
320               if (clearing)
321                 w->next->status = -1;           /* flag that a signal was received */
322               else if (!potential_match || !(w->next->options & WNOHANG))
323                 w->next->ev = NULL;
324               if (!SetEvent (oldw))
325                 system_printf ("couldn't wake up wait event %p, %E", oldw);
326               w->next = w->next->next;
327             }
328           if (w->next == NULL)
329             break;
330         }
331
332       if (!clearing)
333         sigproc_printf ("finished processing terminated/stopped child");
334       else
335         {
336           waitq_head.next = NULL;
337           sigproc_printf ("finished clearing");
338         }
339
340       if (global_sigs[SIGCHLD].sa_handler == (void *) SIG_IGN)
341         for (int i = 0; i < nprocs; i += remove_proc (i))
342           continue;
343   }
344
345 out:
346   sync_proc_subproc.release (); // Release the lock
347 out1:
348   sigproc_printf ("returning %d", rc);
349   return rc;
350 #undef wval
351 #undef vchild
352 }
353
354 // FIXME: This is inelegant
355 void
356 _cygtls::remove_wq (DWORD wait)
357 {
358   if (sync_proc_subproc && sync_proc_subproc.acquire (wait))
359     {
360       for (waitq *w = &waitq_head; w->next != NULL; w = w->next)
361         if (w->next == &wq)
362           {
363             ForceCloseHandle1 (wq.thread_ev, wq_ev);
364             w->next = wq.next;
365             break;
366           }
367       sync_proc_subproc.release ();
368     }
369 }
370
371 /* Terminate the wait_subproc thread.
372  * Called on process exit.
373  * Also called by spawn_guts to disassociate any subprocesses from this
374  * process.  Subprocesses will then know to clean up after themselves and
375  * will not become procs.
376  */
377 void __stdcall
378 proc_terminate ()
379 {
380   sigproc_printf ("nprocs %d", nprocs);
381   if (nprocs)
382     {
383       sync_proc_subproc.acquire (WPSP);
384
385       proc_subproc (PROC_CLEARWAIT, 1);
386
387       /* Clean out proc processes from the pid list. */
388       int i;
389       for (i = 0; i < nprocs; i++)
390         {
391           procs[i]->ppid = 1;
392           if (procs[i].wait_thread)
393             {
394               // CloseHandle (procs[i].rd_proc_pipe);
395               procs[i].wait_thread->terminate_thread ();
396             }
397           procs[i].release ();
398         }
399       nprocs = 0;
400       sync_proc_subproc.release ();
401     }
402   sigproc_printf ("leaving");
403 }
404
405 /* Clear pending signal */
406 void __stdcall
407 sig_clear (int target_sig)
408 {
409   if (&_my_tls != _sig_tls)
410     sig_send (myself, -target_sig);
411   else
412     {
413       sigpacket *q;
414       sigpacket *save = sigq.save ();
415       sigq.reset ();
416       while ((q = sigq.next ()))
417         if (q->si.si_signo == target_sig)
418           {
419             q->si.si_signo = __SIGDELETE;
420             break;
421           }
422       sigq.restore (save);
423     }
424 }
425
426 extern "C" int
427 sigpending (sigset_t *mask)
428 {
429   sigset_t outset = (sigset_t) sig_send (myself, __SIGPENDING);
430   if (outset == SIG_BAD_MASK)
431     return -1;
432   *mask = outset;
433   return 0;
434 }
435
436 /* Force the wait_sig thread to wake up and scan for pending signals */
437 void __stdcall
438 sig_dispatch_pending (bool fast)
439 {
440   if (exit_state || &_my_tls == _sig_tls || !sigq.start.next)
441     {
442 #ifdef DEBUGGING
443       sigproc_printf ("exit_state %d, cur thread id %p, _sig_tls %p, sigq.start.next %p",
444                       exit_state, GetCurrentThreadId (), _sig_tls, sigq.start.next);
445 #endif
446       return;
447     }
448
449 #ifdef DEBUGGING
450   sigproc_printf ("flushing");
451 #endif
452   sig_send (myself, fast ? __SIGFLUSHFAST : __SIGFLUSH);
453 }
454
455 void __stdcall
456 create_signal_arrived ()
457 {
458   if (signal_arrived)
459     return;
460   /* local event signaled when main thread has been dispatched
461      to a signal handler function. */
462   signal_arrived = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
463   ProtectHandle (signal_arrived);
464 }
465
466 /* Signal thread initialization.  Called from dll_crt0_1.
467
468    This routine starts the signal handling thread.  The wait_sig_inited
469    event is used to signal that the thread is ready to handle signals.
470    We don't wait for this during initialization but instead detect it
471    in sig_send to gain a little concurrency.  */
472 void __stdcall
473 sigproc_init ()
474 {
475   wait_sig_inited = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
476   ProtectHandle (wait_sig_inited);
477
478   /* sync_proc_subproc is used by proc_subproc.  It serialises
479    * access to the children and proc arrays.
480    */
481   sync_proc_subproc.init ("sync_proc_subproc");
482
483   my_sendsig = INVALID_HANDLE_VALUE;    // changed later
484   cygthread *hwait_sig = new cygthread (wait_sig, 0, cygself, "sig");
485   hwait_sig->zap_h ();
486
487   global_sigs[SIGSTOP].sa_flags = SA_RESTART | SA_NODEFER;
488   sigproc_printf ("process/signal handling enabled, state %p", myself->process_state);
489 }
490
491 /* Called on process termination to terminate signal and process threads.
492  */
493 void __stdcall
494 sigproc_terminate (exit_states es)
495 {
496   exit_states prior_exit_state = exit_state;
497   exit_state = es;
498   if (prior_exit_state >= ES_FINAL)
499     sigproc_printf ("already performed");
500   else
501     {
502       sigproc_printf ("entering");
503       sig_send (myself_nowait, __SIGEXIT);
504       proc_terminate ();                // clean up process stuff
505     }
506 }
507
508 int __stdcall
509 sig_send (_pinfo *p, int sig)
510 {
511   siginfo_t si;
512   si.si_signo = sig;
513   si.si_code = SI_KERNEL;
514   si.si_pid = si.si_uid = si.si_errno = 0;
515   return sig_send (p, si);
516 }
517
518 /* Send a signal to another process by raising its signal semaphore.
519    If pinfo *p == NULL, send to the current process.
520    If sending to this process, wait for notification that a signal has
521    completed before returning.  */
522 int __stdcall
523 sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
524 {
525   int rc = 1;
526   bool its_me;
527   HANDLE sendsig;
528   sigpacket pack;
529   bool communing = si.si_signo == __SIGCOMMUNE;
530
531   pack.wakeup = NULL;
532   bool wait_for_completion;
533   if (!(its_me = (p == NULL || p == myself || p == myself_nowait)))
534     {
535       /* It is possible that the process is not yet ready to receive messages
536        * or that it has exited.  Detect this.
537        */
538       if (!proc_can_be_signalled (p))   /* Is the process accepting messages? */
539         {
540           sigproc_printf ("invalid pid %d(%x), signal %d",
541                           p->pid, p->process_state, si.si_signo);
542           goto out;
543         }
544       wait_for_completion = false;
545     }
546   else
547     {
548       if (no_signals_available (si.si_signo != __SIGEXIT))
549         {
550           sigproc_printf ("my_sendsig %p, myself->sendsig %p, exit_state %d",
551                           my_sendsig, myself->sendsig, exit_state);
552           set_errno (EAGAIN);
553           goto out;             // Either exiting or not yet initializing
554         }
555       if (wait_sig_inited)
556         wait_for_sigthread ();
557       wait_for_completion = p != myself_nowait && _my_tls.isinitialized () && !exit_state;
558       p = myself;
559     }
560
561
562   if (its_me)
563     sendsig = my_sendsig;
564   else
565     {
566       HANDLE dupsig;
567       DWORD dwProcessId;
568       for (int i = 0; !p->sendsig && i < 10000; i++)
569         low_priority_sleep (0);
570       if (p->sendsig)
571         {
572           dupsig = p->sendsig;
573           dwProcessId = p->dwProcessId;
574         }
575       else
576         {
577           dupsig = p->exec_sendsig;
578           dwProcessId = p->exec_dwProcessId;
579         }
580       if (!dupsig)
581         {
582           set_errno (EAGAIN);
583           sigproc_printf ("sendsig handle never materialized");
584           goto out;
585         }
586       HANDLE hp = OpenProcess (PROCESS_DUP_HANDLE, false, dwProcessId);
587       if (!hp)
588         {
589           __seterrno ();
590           sigproc_printf ("OpenProcess failed, %E");
591           goto out;
592         }
593       VerifyHandle (hp);
594       if (!DuplicateHandle (hp, dupsig, hMainProc, &sendsig, false, 0,
595                             DUPLICATE_SAME_ACCESS) || !sendsig)
596         {
597           __seterrno ();
598           sigproc_printf ("DuplicateHandle failed, %E");
599           CloseHandle (hp);
600           goto out;
601         }
602       VerifyHandle (sendsig);
603       if (!communing)
604         CloseHandle (hp);
605       else
606         {
607           si._si_commune._si_process_handle = hp;
608
609           HANDLE& tome = si._si_commune._si_write_handle;
610           HANDLE& fromthem = si._si_commune._si_read_handle;
611           if (!CreatePipe (&fromthem, &tome, &sec_all_nih, 0))
612             {
613               sigproc_printf ("CreatePipe for __SIGCOMMUNE failed, %E");
614               __seterrno ();
615               goto out;
616             }
617           if (!DuplicateHandle (hMainProc, tome, hp, &tome, false, 0,
618                                 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
619             {
620               sigproc_printf ("DuplicateHandle for __SIGCOMMUNE failed, %E");
621               __seterrno ();
622               goto out;
623             }
624         }
625     }
626
627   sigproc_printf ("sendsig %p, pid %d, signal %d, its_me %d", sendsig, p->pid, si.si_signo, its_me);
628
629   sigset_t pending;
630   if (!its_me)
631     pack.mask = NULL;
632   else if (si.si_signo == __SIGPENDING)
633     pack.mask = &pending;
634   else if (si.si_signo == __SIGFLUSH || si.si_signo > 0)
635     pack.mask = &myself->getsigmask ();
636   else
637     pack.mask = NULL;
638
639   pack.si = si;
640   if (!pack.si.si_pid)
641     pack.si.si_pid = myself->pid;
642   if (!pack.si.si_uid)
643     pack.si.si_uid = myself->uid;
644   pack.pid = myself->pid;
645   pack.tls = (_cygtls *) tls;
646   if (wait_for_completion)
647     {
648       pack.wakeup = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
649       sigproc_printf ("wakeup %p", pack.wakeup);
650       ProtectHandle (pack.wakeup);
651     }
652
653   char *leader;
654   size_t packsize;
655   if (!communing || !(si._si_commune._si_code & PICOM_EXTRASTR))
656     {
657       leader = (char *) &pack;
658       packsize = sizeof (pack);
659     }
660   else
661     {
662       size_t n = strlen (si._si_commune._si_str);
663       char *p = leader = (char *) alloca (sizeof (pack) + sizeof (n) + n);
664       memcpy (p, &pack, sizeof (pack)); p += sizeof (pack);
665       memcpy (p, &n, sizeof (n)); p += sizeof (n);
666       memcpy (p, si._si_commune._si_str, n); p += n;
667       packsize = p - leader;
668     }
669
670   DWORD nb;
671   if (!WriteFile (sendsig, leader, packsize, &nb, NULL) || nb != packsize)
672     {
673       /* Couldn't send to the pipe.  This probably means that the
674          process is exiting.  */
675       if (!its_me)
676         {
677           __seterrno ();
678           sigproc_printf ("WriteFile for pipe %p failed, %E", sendsig);
679           ForceCloseHandle (sendsig);
680         }
681       else
682         {
683           if (no_signals_available (true))
684             sigproc_printf ("I'm going away now");
685           else if (!p->exec_sendsig)
686             system_printf ("error sending signal %d to pid %d, pipe handle %p, %E",
687                            si.si_signo, p->pid, sendsig);
688           set_errno (EACCES);
689         }
690       goto out;
691     }
692
693
694   /* No need to wait for signal completion unless this was a signal to
695      this process.
696
697      If it was a signal to this process, wait for a dispatched signal.
698      Otherwise just wait for the wait_sig to signal that it has finished
699      processing the signal.  */
700   if (wait_for_completion)
701     {
702       sigproc_printf ("Waiting for pack.wakeup %p", pack.wakeup);
703       rc = WaitForSingleObject (pack.wakeup, WSSC);
704       ForceCloseHandle (pack.wakeup);
705     }
706   else
707     {
708       rc = WAIT_OBJECT_0;
709       sigproc_printf ("Not waiting for sigcomplete.  its_me %d signal %d",
710                       its_me, si.si_signo);
711       if (!its_me)
712         ForceCloseHandle (sendsig);
713     }
714
715   pack.wakeup = NULL;
716   if (rc == WAIT_OBJECT_0)
717     rc = 0;             // Successful exit
718   else
719     {
720       if (!no_signals_available (true))
721         system_printf ("wait for sig_complete event failed, signal %d, rc %d, %E",
722                        si.si_signo, rc);
723       set_errno (ENOSYS);
724       rc = -1;
725     }
726
727   if (wait_for_completion && si.si_signo != __SIGFLUSHFAST)
728     _my_tls.call_signal_handler ();
729   goto out;
730
731 out:
732   if (communing && rc)
733     {
734       if (si._si_commune._si_process_handle)
735         CloseHandle (si._si_commune._si_process_handle);
736       if (si._si_commune._si_read_handle)
737         CloseHandle (si._si_commune._si_read_handle);
738     }
739   if (pack.wakeup)
740     ForceCloseHandle (pack.wakeup);
741   if (si.si_signo != __SIGPENDING)
742     /* nothing */;
743   else if (!rc)
744     rc = (int) pending;
745   else
746     rc = SIG_BAD_MASK;
747   sigproc_printf ("returning %p from sending signal %d", rc, si.si_signo);
748   return rc;
749 }
750
751 /* Initialize some of the memory block passed to child processes
752    by fork/spawn/exec. */
753
754 child_info::child_info (unsigned in_cb, child_info_types chtype, bool need_subproc_ready)
755 {
756   memset (this, 0, in_cb);
757   cb = in_cb;
758   intro = PROC_MAGIC_GENERIC;
759   magic = CHILD_INFO_MAGIC;
760   type = chtype;
761   fhandler_union_cb = sizeof (fhandler_union);
762   user_h = cygwin_user_h;
763   if (need_subproc_ready)
764     subproc_ready = CreateEvent (&sec_all, FALSE, FALSE, NULL);
765   sigproc_printf ("subproc_ready %p", subproc_ready);
766   cygheap = ::cygheap;
767   cygheap_max = ::cygheap_max;
768   dwProcessId = myself->dwProcessId;
769   /* Create an inheritable handle to pass to the child process.  This will
770      allow the child to duplicate handles from the parent to itself. */
771   parent = NULL;
772   if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &parent, 0, TRUE,
773                         DUPLICATE_SAME_ACCESS))
774     system_printf ("couldn't create handle to myself for child, %E");
775 }
776
777 child_info::~child_info ()
778 {
779   if (subproc_ready)
780     CloseHandle (subproc_ready);
781   if (parent)
782     CloseHandle (parent);
783 }
784
785 child_info_fork::child_info_fork () :
786   child_info (sizeof *this, _PROC_FORK, true)
787 {
788 }
789
790 child_info_spawn::child_info_spawn (child_info_types chtype, bool need_subproc_ready) :
791   child_info (sizeof *this, chtype, need_subproc_ready)
792 {
793 }
794
795 void
796 child_info::ready (bool execed)
797 {
798   if (!subproc_ready)
799     {
800       sigproc_printf ("subproc_ready not set");
801       return;
802     }
803
804   if (dynamically_loaded)
805     sigproc_printf ("not really ready");
806   else if (!SetEvent (subproc_ready))
807     api_fatal ("SetEvent failed");
808   else
809     sigproc_printf ("signalled %p that I was ready", subproc_ready);
810
811   if (execed)
812     {
813       CloseHandle (subproc_ready);
814       subproc_ready = NULL;
815     }
816 }
817
818 bool
819 child_info::sync (pid_t pid, HANDLE& hProcess, DWORD howlong)
820 {
821   bool res;
822   HANDLE w4[2];
823   unsigned n = 0;
824   unsigned nsubproc_ready;
825
826   if (!subproc_ready)
827     nsubproc_ready = WAIT_OBJECT_0 + 3;
828   else
829     {
830       w4[n++] = subproc_ready;
831       nsubproc_ready = 0;
832     }
833   w4[n++] = hProcess;
834
835   sigproc_printf ("n %d, waiting for subproc_ready(%p) and child process(%p)", n, w4[0], w4[1]);
836   DWORD x = WaitForMultipleObjects (n, w4, FALSE, howlong);
837   x -= WAIT_OBJECT_0;
838   if (x >= n)
839     {
840       system_printf ("wait failed, pid %d, %E", pid);
841       res = false;
842     }
843   else
844     {
845       if (type == _PROC_EXEC && x == nsubproc_ready && myself->wr_proc_pipe)
846         {
847           ForceCloseHandle1 (hProcess, childhProcess);
848           hProcess = NULL;
849         }
850       sigproc_printf ("process %d synchronized, WFMO returned %d", pid, x);
851       res = true;
852     }
853   return res;
854 }
855
856 /* Check the state of all of our children to see if any are stopped or
857  * terminated.
858  */
859 static int __stdcall
860 checkstate (waitq *parent_w)
861 {
862   int potential_match = 0;
863
864   sigproc_printf ("nprocs %d", nprocs);
865
866   /* Check already dead processes first to see if they match the criteria
867    * given in w->next.  */
868   int res;
869   for (int i = 0; i < nprocs; i++)
870     if ((res = stopped_or_terminated (parent_w, procs[i])))
871       {
872         remove_proc (i);
873         potential_match = 1;
874         goto out;
875       }
876
877   sigproc_printf ("no matching terminated children found");
878   potential_match = -!!nprocs;
879
880 out:
881   sigproc_printf ("returning %d", potential_match);
882   return potential_match;
883 }
884
885 /* Remove a proc from procs by swapping it with the last child in the list.
886    Also releases shared memory of exited processes.  */
887 static bool __stdcall
888 remove_proc (int ci)
889 {
890   if (procs[ci]->exists ())
891     return true;
892
893   sigproc_printf ("removing procs[%d], pid %d, nprocs %d", ci, procs[ci]->pid,
894                   nprocs);
895   if (procs[ci] != myself)
896     {
897       procs[ci].release ();
898       if (procs[ci].hProcess)
899         ForceCloseHandle1 (procs[ci].hProcess, childhProc);
900     }
901   if (ci < --nprocs)
902     {
903       /* Wait for proc_waiter thread to make a copy of this element before
904          moving it or it may become confused.  The chances are very high that
905          the proc_waiter thread has already done this by the time we
906          get here.  */
907       while (!procs[nprocs].waiter_ready)
908         low_priority_sleep (0);
909       procs[ci] = procs[nprocs];
910     }
911   return 0;
912 }
913
914 /* Check status of child process vs. waitq member.
915
916    parent_w is the pointer to the parent of the waitq member in question.
917    child is the subprocess being considered.
918
919    Returns non-zero if waiting thread released.  */
920 static bool __stdcall
921 stopped_or_terminated (waitq *parent_w, _pinfo *child)
922 {
923   int might_match;
924   waitq *w = parent_w->next;
925
926   sigproc_printf ("considering pid %d", child->pid);
927   if (w->pid == -1)
928     might_match = 1;
929   else if (w->pid == 0)
930     might_match = child->pgid == myself->pgid;
931   else if (w->pid < 0)
932     might_match = child->pgid == -w->pid;
933   else
934     might_match = (w->pid == child->pid);
935
936   if (!might_match)
937     return 0;
938
939   int terminated;
940
941   if (!((terminated = (child->process_state == PID_EXITED)) ||
942       ((w->options & WUNTRACED) && child->stopsig)))
943     return 0;
944
945   parent_w->next = w->next;     /* successful wait.  remove from wait queue */
946   w->pid = child->pid;
947
948   if (!terminated)
949     {
950       sigproc_printf ("stopped child");
951       w->status = (child->stopsig << 8) | 0x7f;
952       child->stopsig = 0;
953     }
954   else
955     {
956       w->status = (__uint16_t) child->exitcode;
957
958       add_rusage (&myself->rusage_children, &child->rusage_children);
959       add_rusage (&myself->rusage_children, &child->rusage_self);
960
961       if (w->rusage)
962         {
963           add_rusage ((struct rusage *) w->rusage, &child->rusage_children);
964           add_rusage ((struct rusage *) w->rusage, &child->rusage_self);
965         }
966     }
967
968   if (!SetEvent (w->ev))        /* wake up wait4 () immediately */
969     system_printf ("couldn't wake up wait event %p, %E", w->ev);
970   return true;
971 }
972
973 static void
974 talktome (siginfo_t *si, HANDLE readsig)
975 {
976   unsigned size = sizeof (*si);
977   sigproc_printf ("pid %d wants some information", si->si_pid);
978   if (si->_si_commune._si_code & PICOM_EXTRASTR)
979     {
980       size_t n;
981       DWORD nb;
982       if (!ReadFile (readsig, &n, sizeof (n), &nb, NULL) || nb != sizeof (n))
983         return;
984       siginfo_t *newsi = (siginfo_t *) alloca (size += n + 1);
985       *newsi = *si;
986       newsi->_si_commune._si_str = (char *) (newsi + 1);
987       if (!ReadFile (readsig, newsi->_si_commune._si_str, n, &nb, NULL) || nb != n)
988         return;
989       newsi->_si_commune._si_str[n] = '\0';
990       si = newsi;
991     }
992
993   pinfo pi (si->si_pid);
994   if (pi)
995     new cygthread (commune_process, size, si, "commune_process");
996 }
997
998 void
999 pending_signals::add (sigpacket& pack)
1000 {
1001   sigpacket *se;
1002   if (sigs[pack.si.si_signo].si.si_signo)
1003     return;
1004   se = sigs + pack.si.si_signo;
1005   *se = pack;
1006   se->mask = &myself->getsigmask ();
1007   se->next = NULL;
1008   if (end)
1009     end->next = se;
1010   end = se;
1011   if (!start.next)
1012     start.next = se;
1013 }
1014
1015 void
1016 pending_signals::del ()
1017 {
1018   sigpacket *next = curr->next;
1019   prev->next = next;
1020   curr->si.si_signo = 0;
1021 #ifdef DEBUGGING
1022   curr->next = NULL;
1023 #endif
1024   if (end == curr)
1025     end = prev;
1026   curr = next;
1027 }
1028
1029 sigpacket *
1030 pending_signals::next ()
1031 {
1032   sigpacket *res;
1033   prev = curr;
1034   if (!curr || !(curr = curr->next))
1035     res = NULL;
1036   else
1037     res = curr;
1038   return res;
1039 }
1040
1041 /* Process signals by waiting for signal data to arrive in a pipe.
1042    Set a completion event if one was specified. */
1043 static DWORD WINAPI
1044 wait_sig (VOID *)
1045 {
1046   HANDLE readsig;
1047   PSECURITY_ATTRIBUTES sa_buf = (PSECURITY_ATTRIBUTES) alloca (1024);
1048   Static bool holding_signals;
1049
1050   /* Initialization */
1051   SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY);
1052
1053   if (!CreatePipe (&readsig, &myself->sendsig, sec_user_nih (sa_buf), 0))
1054     api_fatal ("couldn't create signal pipe, %E");
1055   ProtectHandle (readsig);
1056   sigCONT = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
1057   my_sendsig = myself->sendsig;
1058
1059   /* Setting dwProcessId flags that this process is now capable of receiving
1060      signals.  Prior to this, dwProcessId was set to the windows pid of
1061      of the original windows process which spawned us unless this was a
1062      "toplevel" process.  */
1063   myself->process_state |= PID_ACTIVE;
1064   myself->process_state &= ~PID_INITIALIZING;
1065
1066   _sig_tls = &_my_tls;
1067   sigproc_printf ("myself->dwProcessId %u", myself->dwProcessId);
1068   SetEvent (wait_sig_inited);
1069
1070   exception_list el;
1071   _sig_tls->init_threadlist_exceptions (&el);
1072   debug_printf ("entering ReadFile loop, readsig %p, myself->sendsig %p",
1073                 readsig, myself->sendsig);
1074
1075   sigpacket pack;
1076   for (;;)
1077     {
1078       DWORD nb;
1079       pack.tls = NULL;
1080       if (!ReadFile (readsig, &pack, sizeof (pack), &nb, NULL))
1081         break;
1082
1083       if (nb != sizeof (pack))
1084         {
1085           system_printf ("short read from signal pipe: %d != %d", nb,
1086                          sizeof (pack));
1087           continue;
1088         }
1089
1090       if (!pack.si.si_signo)
1091         {
1092 #ifdef DEBUGGING
1093           system_printf ("zero signal?");
1094 #endif
1095           continue;
1096         }
1097
1098       sigset_t dummy_mask;
1099       if (!pack.mask)
1100         {
1101           dummy_mask = myself->getsigmask ();
1102           pack.mask = &dummy_mask;
1103         }
1104
1105       sigpacket *q;
1106       bool clearwait = false;
1107       switch (pack.si.si_signo)
1108         {
1109         case __SIGCOMMUNE:
1110           talktome (&pack.si, readsig);
1111           break;
1112         case __SIGSTRACE:
1113           strace.hello ();
1114           break;
1115         case __SIGPENDING:
1116           *pack.mask = 0;
1117           unsigned bit;
1118           sigq.reset ();
1119           while ((q = sigq.next ()))
1120             if (myself->getsigmask () & (bit = SIGTOMASK (q->si.si_signo)))
1121               *pack.mask |= bit;
1122           break;
1123         case __SIGHOLD:
1124           holding_signals = 1;
1125           break;
1126         case __SIGNOHOLD:
1127           holding_signals = 0;
1128           /* fall through, intentionally */
1129         case __SIGFLUSH:
1130         case __SIGFLUSHFAST:
1131           sigq.reset ();
1132           while ((q = sigq.next ()))
1133             {
1134               int sig = q->si.si_signo;
1135               if (sig == __SIGDELETE || q->process () > 0)
1136                 sigq.del ();
1137               if (sig == __SIGNOHOLD && q->si.si_signo == SIGCHLD)
1138                 clearwait = true;
1139             }
1140           break;
1141         case __SIGEXIT:
1142           sigproc_printf ("saw __SIGEXIT");
1143           break;        /* handle below */
1144         default:
1145           if (pack.si.si_signo < 0)
1146             sig_clear (-pack.si.si_signo);
1147           else if (holding_signals)
1148             sigq.add (pack);
1149           else
1150             {
1151               int sig = pack.si.si_signo;
1152               // FIXME: REALLY not right when taking threads into consideration.
1153               // We need a per-thread queue since each thread can have its own
1154               // list of blocked signals.  CGF 2005-08-24
1155               if (sigq.sigs[sig].si.si_signo && sigq.sigs[sig].tls == pack.tls)
1156                 sigproc_printf ("sig %d already queued", pack.si.si_signo);
1157               else
1158                 {
1159                   int sigres = pack.process ();
1160                   if (sigres <= 0)
1161                     {
1162 #ifdef DEBUGGING2
1163                       if (!sigres)
1164                         system_printf ("Failed to arm signal %d from pid %d", pack.sig, pack.pid);
1165 #endif
1166                       sigq.add (pack);  // FIXME: Shouldn't add this in !sh condition
1167                     }
1168                 }
1169               if (sig == SIGCHLD)
1170                 clearwait = true;
1171             }
1172           break;
1173         }
1174       if (clearwait)
1175         proc_subproc (PROC_CLEARWAIT, 0);
1176       if (pack.wakeup)
1177         {
1178           SetEvent (pack.wakeup);
1179           sigproc_printf ("signalled %p", pack.wakeup);
1180         }
1181       if (pack.si.si_signo == __SIGEXIT)
1182         break;
1183     }
1184
1185   ForceCloseHandle (readsig);
1186   sigproc_printf ("signal thread exiting");
1187   ExitThread (0);
1188 }