]> cygwin.com Git - newlib-cygwin.git/blob - winsup/cygwin/sigproc.cc
Revert "Cygwin: fix permission problem when writing DAC info on Samba shares"
[newlib-cygwin.git] / winsup / cygwin / sigproc.cc
1 /* sigproc.cc: inter/intra signal and sub process handler
2
3 This file is part of Cygwin.
4
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
7 details. */
8
9 #include "winsup.h"
10 #include "miscfuncs.h"
11 #include <stdlib.h>
12 #include <sys/cygwin.h>
13 #include "cygerrno.h"
14 #include "sigproc.h"
15 #include "path.h"
16 #include "fhandler.h"
17 #include "dtable.h"
18 #include "cygheap.h"
19 #include "child_info_magic.h"
20 #include "shared_info.h"
21 #include "cygtls.h"
22 #include "ntdll.h"
23 #include "exception.h"
24
25 /*
26 * Convenience defines
27 */
28 #define WSSC 60000 // Wait for signal completion
29 #define WPSP 40000 // Wait for proc_subproc mutex
30
31 /*
32 * Global variables
33 */
34 struct sigaction *global_sigs;
35
36 const char *__sp_fn ;
37 int __sp_ln;
38
39 bool no_thread_exit_protect::flag;
40
41 /* Flag to sig_send that signal goes to current process but no wait is
42 required. */
43 char NO_COPY myself_nowait_dummy[1] = {'0'};
44
45 #define Static static NO_COPY
46
47 /* All my children info. Avoid expensive constructor ops at DLL
48 startup.
49
50 This class can allocate memory. But there's no need to free it
51 because only one instance of the class is created per process. */
52 class child_procs {
53 #ifdef __i386__
54 static const int _NPROCS = 256;
55 static const int _NPROCS_2 = 1023;
56 #else
57 static const int _NPROCS = 1024;
58 static const int _NPROCS_2 = 4095;
59 #endif
60 int _count;
61 uint8_t _procs[_NPROCS * sizeof (pinfo)] __attribute__ ((__aligned__));
62 pinfo *_procs_2;
63 public:
64 int count () const { return _count; }
65 int add_one () { return ++_count; }
66 int del_one () { return --_count; }
67 int reset () { return _count = 0; }
68 pinfo &operator[] (int idx)
69 {
70 if (idx >= _NPROCS)
71 {
72 if (!_procs_2)
73 {
74 /* Use HeapAlloc to avoid propagating this memory area
75 to the child processes. */
76 _procs_2 = (pinfo *) HeapAlloc (GetProcessHeap (),
77 HEAP_GENERATE_EXCEPTIONS
78 | HEAP_ZERO_MEMORY,
79 (_NPROCS_2 + 1) * sizeof (pinfo));
80 }
81 return _procs_2[idx - _NPROCS];
82 }
83 return ((pinfo *) _procs)[idx];
84 }
85 int max_child_procs () const { return _NPROCS + _NPROCS_2; }
86 };
87 Static child_procs chld_procs;
88
89 /* Start of queue for waiting threads. */
90 Static waitq waitq_head;
91
92 /* Controls access to subproc stuff. */
93 Static muto sync_proc_subproc;
94
95 _cygtls NO_COPY *_sig_tls;
96
97 Static HANDLE my_sendsig;
98 Static HANDLE my_readsig;
99
100 /* Used in select if a signalfd is part of the read descriptor set */
101 HANDLE NO_COPY my_pendingsigs_evt;
102
103 /* Function declarations */
104 static int __reg1 checkstate (waitq *);
105 static __inline__ bool get_proc_lock (DWORD, DWORD);
106 static int remove_proc (int);
107 static bool stopped_or_terminated (waitq *, _pinfo *);
108 static void WINAPI wait_sig (VOID *arg);
109
110 /* wait_sig bookkeeping */
111
112 class pending_signals
113 {
114 sigpacket sigs[_NSIG + 1];
115 sigpacket start;
116 bool retry;
117
118 public:
119 void add (sigpacket&);
120 bool pending () {retry = true; return !!start.next;}
121 void clear (int sig) {sigs[sig].si.si_signo = 0;}
122 void clear (_cygtls *tls);
123 friend void __reg1 sig_dispatch_pending (bool);
124 friend void WINAPI wait_sig (VOID *arg);
125 };
126
127 Static pending_signals sigq;
128
129 /* Functions */
130 void
131 sigalloc ()
132 {
133 cygheap->sigs = global_sigs =
134 (struct sigaction *) ccalloc_abort (HEAP_SIGS, _NSIG, sizeof (struct sigaction));
135 global_sigs[SIGSTOP].sa_flags = SA_RESTART | SA_NODEFER;
136 }
137
138 void
139 signal_fixup_after_exec ()
140 {
141 global_sigs = cygheap->sigs;
142 /* Set up child's signal handlers */
143 for (int i = 0; i < _NSIG; i++)
144 {
145 global_sigs[i].sa_mask = 0;
146 if (global_sigs[i].sa_handler != SIG_IGN)
147 {
148 global_sigs[i].sa_handler = SIG_DFL;
149 global_sigs[i].sa_flags &= ~ SA_SIGINFO;
150 }
151 }
152 }
153
154 /* Get the sync_proc_subproc muto to control access to
155 * children, proc arrays.
156 * Attempt to handle case where process is exiting as we try to grab
157 * the mutex.
158 */
159 static bool
160 get_proc_lock (DWORD what, DWORD val)
161 {
162 if (!cygwin_finished_initializing)
163 return true;
164 Static int lastwhat = -1;
165 if (!sync_proc_subproc)
166 {
167 sigproc_printf ("sync_proc_subproc is NULL");
168 return false;
169 }
170 if (sync_proc_subproc.acquire (WPSP))
171 {
172 lastwhat = what;
173 return true;
174 }
175 system_printf ("Couldn't acquire %s for(%d,%d), last %d, %E",
176 sync_proc_subproc.name, what, val, lastwhat);
177 return false;
178 }
179
180 static bool
181 proc_can_be_signalled (_pinfo *p)
182 {
183 if (!(p->exitcode & EXITCODE_SET))
184 {
185 if (ISSTATE (p, PID_INITIALIZING) ||
186 (((p)->process_state & (PID_ACTIVE | PID_IN_USE)) ==
187 (PID_ACTIVE | PID_IN_USE)))
188 return true;
189 }
190
191 set_errno (ESRCH);
192 return false;
193 }
194
195 bool __reg1
196 pid_exists (pid_t pid)
197 {
198 pinfo p (pid);
199 return p && p->exists ();
200 }
201
202 /* Return true if this is one of our children, false otherwise. */
203 static inline bool
204 mychild (int pid)
205 {
206 for (int i = 0; i < chld_procs.count (); i++)
207 if (chld_procs[i]->pid == pid)
208 return true;
209 return false;
210 }
211
212 /* Handle all subprocess requests
213 */
214 int __reg2
215 proc_subproc (DWORD what, uintptr_t val)
216 {
217 int slot;
218 int rc = 1;
219 int potential_match;
220 int clearing;
221 waitq *w;
222
223 #define wval ((waitq *) val)
224 #define vchild (*((pinfo *) val))
225
226 sigproc_printf ("args: %x, %d", what, val);
227
228 if (!get_proc_lock (what, val)) // Serialize access to this function
229 {
230 system_printf ("couldn't get proc lock. what %d, val %d", what, val);
231 goto out1;
232 }
233
234 switch (what)
235 {
236 /* Add a new subprocess to the children arrays.
237 * (usually called from the main thread)
238 */
239 case PROC_ADD_CHILD:
240 /* Filled up process table? */
241 if (chld_procs.count () >= chld_procs.max_child_procs ())
242 {
243 sigproc_printf ("proc table overflow: hit %d processes, pid %d\n",
244 chld_procs.count (), vchild->pid);
245 rc = 0;
246 set_errno (EAGAIN);
247 break;
248 }
249
250 if (vchild != myself)
251 {
252 vchild->uid = myself->uid;
253 vchild->gid = myself->gid;
254 vchild->pgid = myself->pgid;
255 vchild->sid = myself->sid;
256 vchild->ctty = myself->ctty;
257 vchild->cygstarted = true;
258 vchild->process_state |= PID_INITIALIZING;
259 vchild->ppid = myself->pid; /* always set last */
260 }
261 break;
262
263 case PROC_ATTACH_CHILD:
264 slot = chld_procs.count ();
265 chld_procs[slot] = vchild;
266 rc = chld_procs[slot].wait ();
267 if (rc)
268 {
269 sigproc_printf ("added pid %d to proc table, slot %d", vchild->pid,
270 slot);
271 chld_procs.add_one ();
272 }
273 break;
274
275 /* Handle a wait4() operation. Allocates an event for the calling
276 * thread which is signaled when the appropriate pid exits or stops.
277 * (usually called from the main thread)
278 */
279 case PROC_WAIT:
280 wval->ev = NULL; // Don't know event flag yet
281
282 if (wval->pid != -1 && wval->pid && !mychild (wval->pid))
283 goto out; // invalid pid. flag no such child
284
285 wval->status = 0; // Don't know status yet
286 sigproc_printf ("wval->pid %d, wval->options %d", wval->pid, wval->options);
287
288 /* If the first time for this thread, create a new event, otherwise
289 * reset the event.
290 */
291 if ((wval->ev = wval->thread_ev) == NULL)
292 {
293 wval->ev = wval->thread_ev = CreateEvent (&sec_none_nih, TRUE, FALSE,
294 NULL);
295 ProtectHandle1 (wval->ev, wq_ev);
296 }
297
298 ResetEvent (wval->ev);
299 w = waitq_head.next;
300 waitq_head.next = wval; /* Add at the beginning. */
301 wval->next = w; /* Link in rest of the list. */
302 clearing = false;
303 goto scan_wait;
304
305 case PROC_EXEC_CLEANUP:
306 /* Cleanup backwards to eliminate redundant copying of chld_procs
307 array members inside remove_proc. */
308 while (chld_procs.count ())
309 remove_proc (chld_procs.count () - 1);
310 for (w = &waitq_head; w->next != NULL; w = w->next)
311 CloseHandle (w->next->ev);
312 break;
313
314 /* Clear all waiting threads. Called from exceptions.cc prior to
315 the main thread's dispatch to a signal handler function.
316 (called from wait_sig thread) */
317 case PROC_CLEARWAIT:
318 /* Clear all "wait"ing threads. */
319 if (val)
320 sigproc_printf ("clear waiting threads");
321 else
322 sigproc_printf ("looking for processes to reap, count %d",
323 chld_procs.count ());
324 clearing = val;
325
326 scan_wait:
327 /* Scan the linked list of wait()ing threads. If a wait's parameters
328 match this pid, then activate it. */
329 for (w = &waitq_head; w->next != NULL; w = w->next)
330 {
331 if ((potential_match = checkstate (w)) > 0)
332 sigproc_printf ("released waiting thread");
333 else if (!clearing && !(w->next->options & WNOHANG) && potential_match < 0)
334 sigproc_printf ("only found non-terminated children");
335 else if (potential_match <= 0) // nothing matched
336 {
337 sigproc_printf ("waiting thread found no children");
338 HANDLE oldw = w->next->ev;
339 w->next->pid = 0;
340 if (clearing)
341 w->next->status = -1; /* flag that a signal was received */
342 else if (!potential_match || !(w->next->options & WNOHANG))
343 w->next->ev = NULL;
344 if (!SetEvent (oldw))
345 system_printf ("couldn't wake up wait event %p, %E", oldw);
346 w->next = w->next->next;
347 }
348 if (w->next == NULL)
349 break;
350 }
351
352 if (!clearing)
353 sigproc_printf ("finished processing terminated/stopped child");
354 else
355 {
356 waitq_head.next = NULL;
357 sigproc_printf ("finished clearing");
358 }
359
360 if (global_sigs[SIGCHLD].sa_handler == (void *) SIG_IGN)
361 for (int i = 0; i < chld_procs.count (); i += remove_proc (i))
362 continue;
363 }
364
365 out:
366 sync_proc_subproc.release (); // Release the lock
367 out1:
368 sigproc_printf ("returning %d", rc);
369 return rc;
370 #undef wval
371 #undef vchild
372 }
373
374 // FIXME: This is inelegant
375 void
376 _cygtls::remove_wq (DWORD wait)
377 {
378 if (wq.thread_ev)
379 {
380 if (exit_state < ES_FINAL && waitq_head.next && sync_proc_subproc
381 && sync_proc_subproc.acquire (wait))
382 {
383 ForceCloseHandle1 (wq.thread_ev, wq_ev);
384 wq.thread_ev = NULL;
385 for (waitq *w = &waitq_head; w->next != NULL; w = w->next)
386 if (w->next == &wq)
387 {
388 w->next = wq.next;
389 break;
390 }
391 sync_proc_subproc.release ();
392 }
393 }
394
395 }
396
397 /* Terminate the wait_subproc thread.
398 Called on process exit.
399 Also called by spawn_guts to disassociate any subprocesses from this
400 process. Subprocesses will then know to clean up after themselves and
401 will not become chld_procs. */
402 void
403 proc_terminate ()
404 {
405 sigproc_printf ("child_procs count %d", chld_procs.count ());
406 if (chld_procs.count ())
407 {
408 sync_proc_subproc.acquire (WPSP);
409
410 proc_subproc (PROC_CLEARWAIT, 1);
411
412 /* Clean out proc processes from the pid list. */
413 for (int i = 0; i < chld_procs.count (); i++)
414 {
415 /* If we've execed then the execed process will handle setting ppid
416 to 1 iff it is a Cygwin process. */
417 if (!have_execed || !have_execed_cygwin)
418 chld_procs[i]->ppid = 1;
419 if (chld_procs[i].wait_thread)
420 chld_procs[i].wait_thread->terminate_thread ();
421 /* Release memory associated with this process unless it is 'myself'.
422 'myself' is only in the chld_procs table when we've execed. We
423 reach here when the next process has finished initializing but we
424 still can't free the memory used by 'myself' since it is used
425 later on during cygwin tear down. */
426 if (chld_procs[i] != myself)
427 chld_procs[i].release ();
428 }
429 chld_procs.reset ();
430 sync_proc_subproc.release ();
431 }
432 sigproc_printf ("leaving");
433 }
434
435 /* Clear pending signal */
436 void __reg1
437 sig_clear (int sig)
438 {
439 sigq.clear (sig);
440 }
441
442 /* Clear pending signals of specific thread. Called under TLS lock from
443 _cygtls::remove_pending_sigs. */
444 void
445 pending_signals::clear (_cygtls *tls)
446 {
447 sigpacket *q = &start, *qnext;
448
449 while ((qnext = q->next))
450 if (qnext->sigtls == tls)
451 {
452 qnext->si.si_signo = 0;
453 q->next = qnext->next;
454 }
455 else
456 q = qnext;
457 }
458
459 /* Clear pending signals of specific thread. Called from _cygtls::remove */
460 void
461 _cygtls::remove_pending_sigs ()
462 {
463 sigq.clear (this);
464 }
465
466 extern "C" int
467 sigpending (sigset_t *mask)
468 {
469 sigset_t outset = sig_send (myself, __SIGPENDING, &_my_tls);
470 if (outset == SIG_BAD_MASK)
471 return -1;
472 *mask = outset;
473 return 0;
474 }
475
476 /* Force the wait_sig thread to wake up and scan for pending signals */
477 void __reg1
478 sig_dispatch_pending (bool fast)
479 {
480 /* Non-atomically test for any signals pending and wake up wait_sig if any are
481 found. It's ok if there's a race here since the next call to this function
482 should catch it. */
483 if (sigq.pending () && &_my_tls != _sig_tls)
484 sig_send (myself, fast ? __SIGFLUSHFAST : __SIGFLUSH);
485 }
486
487 /* Signal thread initialization. Called from dll_crt0_1.
488 This routine starts the signal handling thread. */
489 void
490 sigproc_init ()
491 {
492 char char_sa_buf[1024];
493 PSECURITY_ATTRIBUTES sa = sec_user_nih ((PSECURITY_ATTRIBUTES) char_sa_buf, cygheap->user.sid());
494 DWORD err = fhandler_pipe::create (sa, &my_readsig, &my_sendsig,
495 _NSIG * sizeof (sigpacket), "sigwait",
496 PIPE_ADD_PID);
497 if (err)
498 {
499 SetLastError (err);
500 api_fatal ("couldn't create signal pipe, %E");
501 }
502 ProtectHandle (my_readsig);
503 myself->sendsig = my_sendsig;
504 my_pendingsigs_evt = CreateEvent (NULL, TRUE, FALSE, NULL);
505 if (!my_pendingsigs_evt)
506 api_fatal ("couldn't create pending signal event, %E");
507
508 /* sync_proc_subproc is used by proc_subproc. It serializes
509 access to the children and proc arrays. */
510 sync_proc_subproc.init ("sync_proc_subproc");
511 new cygthread (wait_sig, cygself, "sig");
512 }
513
514 /* Exit the current thread very carefully.
515 See cgf-000017 in DevNotes for more details on why this is
516 necessary. */
517 void
518 exit_thread (DWORD res)
519 {
520 # undef ExitThread
521 if (no_thread_exit_protect ())
522 ExitThread (res);
523 sigfillset (&_my_tls.sigmask); /* No signals wanted */
524
525 /* CV 2014-11-21: Disable the code sending a signal. The problem with
526 this code is that it allows deadlocks under signal-rich multithreading
527 conditions.
528 The original problem reported in 2012 couldn't be reproduced anymore,
529 even disabling this code. Tested on XP 32, Vista 32, W7 32, WOW64, 64,
530 W8.1 WOW64, 64. */
531 #if 0
532 lock_process for_now; /* May block indefinitely when exiting. */
533 HANDLE h;
534 if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
535 GetCurrentProcess (), &h,
536 0, FALSE, DUPLICATE_SAME_ACCESS))
537 {
538 #ifdef DEBUGGING
539 system_printf ("couldn't duplicate the current thread, %E");
540 #endif
541 for_now.release ();
542 ExitThread (res);
543 }
544 ProtectHandle1 (h, exit_thread);
545 /* Tell wait_sig to wait for this thread to exit. It can then release
546 the lock below and close the above-opened handle. */
547 siginfo_t si = {__SIGTHREADEXIT, SI_KERNEL};
548 si.si_cyg = h;
549 sig_send (myself_nowait, si, &_my_tls);
550 #endif
551 ExitThread (res);
552 }
553
554 sigset_t __reg3
555 sig_send (_pinfo *p, int sig, _cygtls *tls)
556 {
557 siginfo_t si = {};
558 si.si_signo = sig;
559 si.si_code = SI_KERNEL;
560 return sig_send (p, si, tls);
561 }
562
563 /* Send a signal to another process by raising its signal semaphore.
564 If pinfo *p == NULL, send to the current process.
565 If sending to this process, wait for notification that a signal has
566 completed before returning. */
567 sigset_t __reg3
568 sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
569 {
570 int rc = 1;
571 bool its_me;
572 HANDLE sendsig;
573 sigpacket pack;
574 bool communing = si.si_signo == __SIGCOMMUNE;
575
576 pack.wakeup = NULL;
577 bool wait_for_completion;
578 if (!(its_me = p == NULL || p == myself || p == myself_nowait))
579 {
580 /* It is possible that the process is not yet ready to receive messages
581 * or that it has exited. Detect this.
582 */
583 if (!proc_can_be_signalled (p)) /* Is the process accepting messages? */
584 {
585 sigproc_printf ("invalid pid %d(%x), signal %d",
586 p->pid, p->process_state, si.si_signo);
587 goto out;
588 }
589 wait_for_completion = false;
590 }
591 else
592 {
593 wait_for_completion = p != myself_nowait;
594 p = myself;
595 }
596
597 /* If myself is the stub process, send signal to the child process
598 rather than myself. The fact that myself->dwProcessId is not equal
599 to the current process id indicates myself is the stub process. */
600 if (its_me && myself->dwProcessId != GetCurrentProcessId ())
601 {
602 wait_for_completion = false;
603 its_me = false;
604 }
605
606 if (its_me)
607 sendsig = my_sendsig;
608 else
609 {
610 HANDLE dupsig;
611 DWORD dwProcessId;
612 for (int i = 0; !p->sendsig && i < 10000; i++)
613 yield ();
614 if (p->sendsig)
615 {
616 dupsig = p->sendsig;
617 dwProcessId = p->dwProcessId;
618 }
619 else
620 {
621 dupsig = p->exec_sendsig;
622 dwProcessId = p->exec_dwProcessId;
623 }
624 if (!dupsig)
625 {
626 set_errno (EAGAIN);
627 sigproc_printf ("sendsig handle never materialized");
628 goto out;
629 }
630 HANDLE hp = OpenProcess (PROCESS_DUP_HANDLE, false, dwProcessId);
631 if (!hp)
632 {
633 __seterrno ();
634 sigproc_printf ("OpenProcess failed, %E");
635 goto out;
636 }
637 VerifyHandle (hp);
638 if (!DuplicateHandle (hp, dupsig, GetCurrentProcess (), &sendsig, 0,
639 false, DUPLICATE_SAME_ACCESS) || !sendsig)
640 {
641 __seterrno ();
642 sigproc_printf ("DuplicateHandle failed, %E");
643 CloseHandle (hp);
644 goto out;
645 }
646 VerifyHandle (sendsig);
647 if (!communing)
648 {
649 CloseHandle (hp);
650 DWORD flag = PIPE_NOWAIT;
651 /* Set PIPE_NOWAIT here to avoid blocking when sending a signal.
652 (Yes, I know MSDN says not to use this)
653 We can't ever block here because it causes a deadlock when
654 debugging with gdb. */
655 BOOL res = SetNamedPipeHandleState (sendsig, &flag, NULL, NULL);
656 sigproc_printf ("%d = SetNamedPipeHandleState (%y, PIPE_NOWAIT, NULL, NULL)", res, sendsig);
657 }
658 else
659 {
660 si._si_commune._si_process_handle = hp;
661
662 HANDLE& tome = si._si_commune._si_write_handle;
663 HANDLE& fromthem = si._si_commune._si_read_handle;
664 if (!CreatePipeOverlapped (&fromthem, &tome, &sec_all_nih))
665 {
666 sigproc_printf ("CreatePipe for __SIGCOMMUNE failed, %E");
667 __seterrno ();
668 goto out;
669 }
670 if (!DuplicateHandle (GetCurrentProcess (), tome, hp, &tome, 0, false,
671 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
672 {
673 sigproc_printf ("DuplicateHandle for __SIGCOMMUNE failed, %E");
674 __seterrno ();
675 goto out;
676 }
677 }
678 }
679
680 sigproc_printf ("sendsig %p, pid %d, signal %d, its_me %d", sendsig, p->pid,
681 si.si_signo, its_me);
682
683 sigset_t pending;
684 if (!its_me)
685 pack.mask = NULL;
686 else if (si.si_signo == __SIGPENDING)
687 pack.mask = &pending;
688 else if (si.si_signo == __SIGFLUSH || si.si_signo > 0)
689 {
690 threadlist_t *tl_entry = cygheap->find_tls (tls ? tls : _main_tls);
691 pack.mask = tls ? &tls->sigmask : &_main_tls->sigmask;
692 cygheap->unlock_tls (tl_entry);
693 }
694 else
695 pack.mask = NULL;
696
697 pack.si = si;
698 if (!pack.si.si_pid)
699 pack.si.si_pid = myself->pid;
700 if (!pack.si.si_uid)
701 pack.si.si_uid = myself->uid;
702 pack.pid = myself->pid;
703 pack.sigtls = tls;
704 if (wait_for_completion)
705 {
706 pack.wakeup = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
707 sigproc_printf ("wakeup %p", pack.wakeup);
708 ProtectHandle (pack.wakeup);
709 }
710
711 char *leader;
712 size_t packsize;
713 if (!communing || !(si._si_commune._si_code & PICOM_EXTRASTR))
714 {
715 leader = (char *) &pack;
716 packsize = sizeof (pack);
717 }
718 else
719 {
720 size_t n = strlen (si._si_commune._si_str);
721 packsize = sizeof (pack) + sizeof (n) + n;
722 char *p = leader = (char *) alloca (packsize);
723 memcpy (p, &pack, sizeof (pack)); p += sizeof (pack);
724 memcpy (p, &n, sizeof (n)); p += sizeof (n);
725 memcpy (p, si._si_commune._si_str, n); p += n;
726 }
727
728 DWORD nb;
729 BOOL res;
730 /* Try multiple times to send if packsize != nb since that probably
731 means that the pipe buffer is full. */
732 for (int i = 0; i < 100; i++)
733 {
734 res = WriteFile (sendsig, leader, packsize, &nb, NULL);
735 if (!res || packsize == nb)
736 break;
737 Sleep (10);
738 res = 0;
739 }
740
741 if (!res)
742 {
743 /* Couldn't send to the pipe. This probably means that the
744 process is exiting. */
745 if (!its_me)
746 {
747 sigproc_printf ("WriteFile for pipe %p failed, %E", sendsig);
748 ForceCloseHandle (sendsig);
749 }
750 else if (!p->exec_sendsig && !exit_state)
751 system_printf ("error sending signal %d, pid %u, pipe handle %p, nb %u, packsize %u, %E",
752 si.si_signo, p->pid, sendsig, nb, packsize);
753 if (GetLastError () == ERROR_BROKEN_PIPE)
754 set_errno (ESRCH);
755 else
756 __seterrno ();
757 goto out;
758 }
759
760
761 /* No need to wait for signal completion unless this was a signal to
762 this process.
763
764 If it was a signal to this process, wait for a dispatched signal.
765 Otherwise just wait for the wait_sig to signal that it has finished
766 processing the signal. */
767 if (wait_for_completion)
768 {
769 sigproc_printf ("Waiting for pack.wakeup %p", pack.wakeup);
770 rc = WaitForSingleObject (pack.wakeup, WSSC);
771 ForceCloseHandle (pack.wakeup);
772 }
773 else
774 {
775 rc = WAIT_OBJECT_0;
776 sigproc_printf ("Not waiting for sigcomplete. its_me %d signal %d",
777 its_me, si.si_signo);
778 if (!its_me)
779 ForceCloseHandle (sendsig);
780 }
781
782 pack.wakeup = NULL;
783 if (rc == WAIT_OBJECT_0)
784 rc = 0; // Successful exit
785 else
786 {
787 set_errno (ENOSYS);
788 rc = -1;
789 }
790
791 if (wait_for_completion && si.si_signo != __SIGFLUSHFAST)
792 _my_tls.call_signal_handler ();
793
794 out:
795 if (communing && rc)
796 {
797 if (si._si_commune._si_process_handle)
798 CloseHandle (si._si_commune._si_process_handle);
799 if (si._si_commune._si_read_handle)
800 CloseHandle (si._si_commune._si_read_handle);
801 }
802 if (pack.wakeup)
803 ForceCloseHandle (pack.wakeup);
804 if (si.si_signo != __SIGPENDING)
805 /* nothing */;
806 else if (!rc)
807 rc = pending;
808 else
809 rc = SIG_BAD_MASK;
810 sigproc_printf ("returning %p from sending signal %d", rc, si.si_signo);
811 return rc;
812 }
813
814 int child_info::retry_count = 0;
815
816 /* Initialize some of the memory block passed to child processes
817 by fork/spawn/exec. */
818 child_info::child_info (unsigned in_cb, child_info_types chtype,
819 bool need_subproc_ready):
820 cb (in_cb), intro (PROC_MAGIC_GENERIC), magic (CHILD_INFO_MAGIC),
821 type (chtype), cygheap (::cygheap), cygheap_max (::cygheap_max),
822 flag (0), retry (child_info::retry_count), rd_proc_pipe (NULL),
823 wr_proc_pipe (NULL)
824 {
825 /* It appears that when running under WOW64 on Vista 64, the first DWORD
826 value in the datastructure lpReserved2 is pointing to (msv_count in
827 Cygwin), has to reflect the size of that datastructure as used in the
828 Microsoft C runtime (a count value, counting the number of elements in
829 two subsequent arrays, BYTE[count and HANDLE[count]), even though the C
830 runtime isn't used. Otherwise, if msv_count is 0 or too small, the
831 datastructure gets overwritten.
832
833 This seems to be a bug in Vista's WOW64, which apparently copies the
834 lpReserved2 datastructure not using the cbReserved2 size information,
835 but using the information given in the first DWORD within lpReserved2
836 instead. However, it's not clear if a non-0 count doesn't result in
837 trying to evaluate the content, so we do this really only for Vista 64.
838
839 The value is sizeof (child_info_*) / 5 which results in a count which
840 covers the full datastructure, plus not more than 4 extra bytes. This
841 is ok as long as the child_info structure is cosily stored within a bigger
842 datastructure. */
843 msv_count = wincap.needs_count_in_si_lpres2 () ? in_cb / 5 : 0;
844
845 fhandler_union_cb = sizeof (fhandler_union);
846 user_h = cygwin_user_h;
847 if (strace.active ())
848 {
849 NTSTATUS status;
850 ULONG DebugFlags;
851
852 /* Only propagate _CI_STRACED to child if strace is actually tracing
853 child processes of this process. The undocumented ProcessDebugFlags
854 returns 0 if EPROCESS->NoDebugInherit is TRUE, 1 otherwise.
855 This avoids a hang when stracing a forking or spawning process
856 with the -f flag set to "don't follow fork". */
857 status = NtQueryInformationProcess (GetCurrentProcess (),
858 ProcessDebugFlags, &DebugFlags,
859 sizeof (DebugFlags), NULL);
860 if (NT_SUCCESS (status) && DebugFlags)
861 flag |= _CI_STRACED;
862 }
863 if (need_subproc_ready)
864 {
865 subproc_ready = CreateEvent (&sec_all, FALSE, FALSE, NULL);
866 flag |= _CI_ISCYGWIN;
867 }
868 sigproc_printf ("subproc_ready %p", subproc_ready);
869 /* Create an inheritable handle to pass to the child process. This will
870 allow the child to copy cygheap etc. from the parent to itself. If
871 we're forking, we also need handle duplicate access. */
872 parent = NULL;
873 DWORD perms = PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ
874 | PROCESS_VM_OPERATION | SYNCHRONIZE;
875 if (type == _CH_FORK)
876 {
877 perms |= PROCESS_DUP_HANDLE;
878 /* VirtualQueryEx is documented to require PROCESS_QUERY_INFORMATION.
879 That's true for Windows 7, but PROCESS_QUERY_LIMITED_INFORMATION
880 appears to be sufficient on Windows 8 and later. */
881 if (wincap.needs_query_information ())
882 perms |= PROCESS_QUERY_INFORMATION;
883 }
884
885 if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),
886 GetCurrentProcess (), &parent, perms, TRUE, 0))
887 system_printf ("couldn't create handle to myself for child, %E");
888 }
889
890 child_info::~child_info ()
891 {
892 cleanup ();
893 }
894
895 child_info_fork::child_info_fork () :
896 child_info (sizeof *this, _CH_FORK, true),
897 forker_finished (NULL)
898 {
899 }
900
901 child_info_spawn::child_info_spawn (child_info_types chtype, bool need_subproc_ready) :
902 child_info (sizeof *this, chtype, need_subproc_ready)
903 {
904 if (type == _CH_EXEC)
905 {
906 hExeced = NULL;
907 if (my_wr_proc_pipe)
908 ev = NULL;
909 else if (!(ev = CreateEvent (&sec_none_nih, false, false, NULL)))
910 api_fatal ("couldn't create signalling event for exec, %E");
911
912 get_proc_lock (PROC_EXECING, 0);
913 /* exit with lock held */
914 }
915 }
916
917 cygheap_exec_info *
918 cygheap_exec_info::alloc ()
919 {
920 cygheap_exec_info *res =
921 (cygheap_exec_info *) ccalloc_abort (HEAP_1_EXEC, 1,
922 sizeof (cygheap_exec_info)
923 + (chld_procs.count ()
924 * sizeof (children[0])));
925 res->sigmask = _my_tls.sigmask;
926 return res;
927 }
928
929 void
930 child_info_spawn::wait_for_myself ()
931 {
932 postfork (myself);
933 if (myself.remember ())
934 myself.attach ();
935 WaitForSingleObject (ev, INFINITE);
936 }
937
938 void
939 child_info::cleanup ()
940 {
941 if (subproc_ready)
942 {
943 CloseHandle (subproc_ready);
944 subproc_ready = NULL;
945 }
946 if (parent)
947 {
948 CloseHandle (parent);
949 parent = NULL;
950 }
951 if (rd_proc_pipe)
952 {
953 ForceCloseHandle (rd_proc_pipe);
954 rd_proc_pipe = NULL;
955 }
956 if (wr_proc_pipe)
957 {
958 ForceCloseHandle (wr_proc_pipe);
959 wr_proc_pipe = NULL;
960 }
961 }
962
963 void
964 child_info_spawn::cleanup ()
965 {
966 if (moreinfo)
967 {
968 if (moreinfo->envp)
969 {
970 for (char **e = moreinfo->envp; *e; e++)
971 cfree (*e);
972 cfree (moreinfo->envp);
973 }
974 if (type != _CH_SPAWN && moreinfo->myself_pinfo)
975 CloseHandle (moreinfo->myself_pinfo);
976 cfree (moreinfo);
977 }
978 moreinfo = NULL;
979 if (ev)
980 {
981 CloseHandle (ev);
982 ev = NULL;
983 }
984 if (type == _CH_EXEC)
985 {
986 if (iscygwin () && hExeced)
987 proc_subproc (PROC_EXEC_CLEANUP, 0);
988 sync_proc_subproc.release ();
989 }
990 type = _CH_NADA;
991 child_info::cleanup ();
992 }
993
994 /* Record any non-reaped subprocesses to be passed to about-to-be-execed
995 process. FIXME: There is a race here if the process exits while we
996 are recording it. */
997 inline void
998 cygheap_exec_info::record_children ()
999 {
1000 for (nchildren = 0; nchildren < chld_procs.count (); nchildren++)
1001 {
1002 children[nchildren].pid = chld_procs[nchildren]->pid;
1003 children[nchildren].p = chld_procs[nchildren];
1004 /* Set inheritance of required child handles for reattach_children
1005 in the about-to-be-execed process. */
1006 children[nchildren].p.set_inheritance (true);
1007 }
1008 }
1009
1010 void
1011 child_info_spawn::record_children ()
1012 {
1013 if (type == _CH_EXEC && iscygwin ())
1014 moreinfo->record_children ();
1015 }
1016
1017 /* Reattach non-reaped subprocesses passed in from the cygwin process
1018 which previously operated under this pid. FIXME: Is there a race here
1019 if the process exits during cygwin's exec handoff? */
1020 inline void
1021 cygheap_exec_info::reattach_children (HANDLE parent)
1022 {
1023 for (int i = 0; i < nchildren; i++)
1024 {
1025 pinfo p (parent, children[i].p, children[i].pid);
1026 if (!p)
1027 debug_only_printf ("couldn't reattach child %d from previous process", children[i].pid);
1028 else if (!p.attach ())
1029 debug_only_printf ("attach of child process %d failed", children[i].pid);
1030 else
1031 debug_only_printf ("reattached pid %d<%u>, process handle %p, rd_proc_pipe %p->%p",
1032 p->pid, p->dwProcessId, p.hProcess,
1033 children[i].p.rd_proc_pipe, p.rd_proc_pipe);
1034 }
1035 }
1036
1037 void
1038 child_info_spawn::reattach_children ()
1039 {
1040 moreinfo->reattach_children (parent);
1041 }
1042
1043 void
1044 child_info::ready (bool execed)
1045 {
1046 if (!subproc_ready)
1047 {
1048 sigproc_printf ("subproc_ready not set");
1049 return;
1050 }
1051
1052 if (dynamically_loaded)
1053 sigproc_printf ("not really ready");
1054 else if (!SetEvent (subproc_ready))
1055 api_fatal ("SetEvent failed, %E");
1056 else
1057 sigproc_printf ("signalled %p that I was ready", subproc_ready);
1058
1059 if (execed)
1060 {
1061 CloseHandle (subproc_ready);
1062 subproc_ready = NULL;
1063 }
1064 }
1065
1066 bool
1067 child_info::sync (pid_t pid, HANDLE& hProcess, DWORD howlong)
1068 {
1069 bool res;
1070 HANDLE w4[2];
1071 unsigned n = 0;
1072 unsigned nsubproc_ready;
1073
1074 if (!subproc_ready)
1075 nsubproc_ready = WAIT_OBJECT_0 + 3;
1076 else
1077 {
1078 w4[n++] = subproc_ready;
1079 nsubproc_ready = 0;
1080 }
1081 w4[n++] = hProcess;
1082
1083 sigproc_printf ("n %d, waiting for subproc_ready(%p) and child process(%p)", n, w4[0], w4[1]);
1084 DWORD x = WaitForMultipleObjects (n, w4, FALSE, howlong);
1085 x -= WAIT_OBJECT_0;
1086 if (x >= n)
1087 {
1088 system_printf ("wait failed, pid %u, %E", pid);
1089 res = false;
1090 }
1091 else
1092 {
1093 if (x != nsubproc_ready)
1094 {
1095 res = false;
1096 GetExitCodeProcess (hProcess, &exit_code);
1097 }
1098 else
1099 {
1100 res = true;
1101 exit_code = STILL_ACTIVE;
1102 if (type == _CH_EXEC && my_wr_proc_pipe)
1103 {
1104 ForceCloseHandle1 (hProcess, childhProc);
1105 hProcess = NULL;
1106 }
1107 }
1108 sigproc_printf ("pid %u, WFMO returned %d, exit_code %y, res %d", pid, x,
1109 exit_code, res);
1110 }
1111 return res;
1112 }
1113
1114 DWORD
1115 child_info::proc_retry (HANDLE h)
1116 {
1117 if (!exit_code)
1118 return EXITCODE_OK;
1119 sigproc_printf ("exit_code %y", exit_code);
1120 switch (exit_code)
1121 {
1122 case STILL_ACTIVE: /* shouldn't happen */
1123 sigproc_printf ("STILL_ACTIVE? How'd we get here?");
1124 break;
1125 case STATUS_DLL_NOT_FOUND:
1126 case STATUS_ACCESS_VIOLATION:
1127 case STATUS_ILLEGAL_INSTRUCTION:
1128 case STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION: /* pseudo-reloc.c specific */
1129 return exit_code;
1130 case STATUS_CONTROL_C_EXIT:
1131 if (saw_ctrl_c ())
1132 return EXITCODE_OK;
1133 fallthrough;
1134 case STATUS_DLL_INIT_FAILED:
1135 case STATUS_DLL_INIT_FAILED_LOGOFF:
1136 case EXITCODE_RETRY:
1137 if (retry-- > 0)
1138 exit_code = 0;
1139 break;
1140 case EXITCODE_FORK_FAILED: /* windows prevented us from forking */
1141 break;
1142
1143 /* Count down non-recognized exit codes more quickly since they aren't
1144 due to known conditions. */
1145 default:
1146 if (!iscygwin () && (exit_code & 0xffff0000) != 0xc0000000)
1147 break;
1148 if ((retry -= 2) < 0)
1149 retry = 0;
1150 else
1151 exit_code = 0;
1152 }
1153 if (!exit_code)
1154 ForceCloseHandle1 (h, childhProc);
1155 return exit_code;
1156 }
1157
1158 bool
1159 child_info_fork::abort (const char *fmt, ...)
1160 {
1161 if (fmt)
1162 {
1163 va_list ap;
1164 va_start (ap, fmt);
1165 if (silentfail ())
1166 strace_vprintf (DEBUG, fmt, ap);
1167 else
1168 strace_vprintf (SYSTEM, fmt, ap);
1169 TerminateProcess (GetCurrentProcess (), EXITCODE_FORK_FAILED);
1170 }
1171 if (retry > 0)
1172 TerminateProcess (GetCurrentProcess (), EXITCODE_RETRY);
1173 return false;
1174 }
1175
1176 /* Check the state of all of our children to see if any are stopped or
1177 * terminated.
1178 */
1179 static int __reg1
1180 checkstate (waitq *parent_w)
1181 {
1182 int potential_match = 0;
1183
1184 sigproc_printf ("child_procs count %d", chld_procs.count ());
1185
1186 /* Check already dead processes first to see if they match the criteria
1187 * given in w->next. */
1188 int res;
1189 for (int i = 0; i < chld_procs.count (); i++)
1190 if ((res = stopped_or_terminated (parent_w, chld_procs[i])))
1191 {
1192 remove_proc (i);
1193 potential_match = 1;
1194 goto out;
1195 }
1196
1197 sigproc_printf ("no matching terminated children found");
1198 potential_match = -!!chld_procs.count ();
1199
1200 out:
1201 sigproc_printf ("returning %d", potential_match);
1202 return potential_match;
1203 }
1204
1205 /* Remove a proc from chld_procs by swapping it with the last child in the list.
1206 Also releases shared memory of exited processes. */
1207 static int
1208 remove_proc (int ci)
1209 {
1210 if (have_execed)
1211 {
1212 if (_my_tls._ctinfo != chld_procs[ci].wait_thread)
1213 chld_procs[ci].wait_thread->terminate_thread ();
1214 }
1215 else if (chld_procs[ci] && chld_procs[ci]->exists ())
1216 return 1;
1217
1218 sigproc_printf ("removing chld_procs[%d], pid %d, child_procs count %d",
1219 ci, chld_procs[ci]->pid, chld_procs.count ());
1220 if (chld_procs[ci] != myself)
1221 chld_procs[ci].release ();
1222 if (ci < chld_procs.del_one ())
1223 {
1224 /* Wait for proc_waiter thread to make a copy of this element before
1225 moving it or it may become confused. The chances are very high that
1226 the proc_waiter thread has already done this by the time we
1227 get here. */
1228 if (!have_execed && !exit_state)
1229 while (!chld_procs[chld_procs.count ()].waiter_ready)
1230 yield ();
1231 chld_procs[ci] = chld_procs[chld_procs.count ()];
1232 }
1233 return 0;
1234 }
1235
1236 /* Check status of child process vs. waitq member.
1237
1238 parent_w is the pointer to the parent of the waitq member in question.
1239 child is the subprocess being considered.
1240
1241 Returns non-zero if waiting thread released. */
1242 static bool
1243 stopped_or_terminated (waitq *parent_w, _pinfo *child)
1244 {
1245 int might_match;
1246 waitq *w = parent_w->next;
1247
1248 sigproc_printf ("considering pid %d, pgid %d, w->pid %d", child->pid, child->pgid, w->pid);
1249 if (w->pid == -1)
1250 might_match = 1;
1251 else if (w->pid == 0)
1252 might_match = child->pgid == myself->pgid;
1253 else if (w->pid < 0)
1254 might_match = child->pgid == -w->pid;
1255 else
1256 might_match = (w->pid == child->pid);
1257
1258 if (!might_match)
1259 return false;
1260
1261 int terminated;
1262
1263 if (!((terminated = (child->process_state == PID_EXITED))
1264 || ((w->options & WCONTINUED) && child->stopsig == SIGCONT)
1265 || ((w->options & WUNTRACED) && child->stopsig && child->stopsig != SIGCONT)))
1266 return false;
1267
1268 parent_w->next = w->next; /* successful wait. remove from wait queue */
1269 w->pid = child->pid;
1270
1271 if (!terminated)
1272 {
1273 sigproc_printf ("stopped child, stop signal %d", child->stopsig);
1274 if (child->stopsig == SIGCONT)
1275 w->status = __W_CONTINUED;
1276 else
1277 w->status = (child->stopsig << 8) | 0x7f;
1278 child->stopsig = 0;
1279 }
1280 else
1281 {
1282 child->process_state = PID_REAPED;
1283 w->status = (__uint16_t) child->exitcode;
1284
1285 add_rusage (&myself->rusage_children, &child->rusage_children);
1286 add_rusage (&myself->rusage_children, &child->rusage_self);
1287
1288 if (w->rusage)
1289 {
1290 add_rusage ((struct rusage *) w->rusage, &child->rusage_children);
1291 add_rusage ((struct rusage *) w->rusage, &child->rusage_self);
1292 }
1293 }
1294
1295 if (!SetEvent (w->ev)) /* wake up wait4 () immediately */
1296 system_printf ("couldn't wake up wait event %p, %E", w->ev);
1297 return true;
1298 }
1299
1300 static void
1301 talktome (siginfo_t *si)
1302 {
1303 unsigned size = sizeof (*si);
1304 sigproc_printf ("pid %d wants some information", si->si_pid);
1305 if (si->_si_commune._si_code & PICOM_EXTRASTR)
1306 {
1307 size_t n;
1308 DWORD nb;
1309 if (!ReadFile (my_readsig, &n, sizeof (n), &nb, NULL) || nb != sizeof (n))
1310 return;
1311 siginfo_t *newsi = (siginfo_t *) alloca (size += n + 1);
1312 *newsi = *si;
1313 newsi->_si_commune._si_str = (char *) (newsi + 1);
1314 if (!ReadFile (my_readsig, newsi->_si_commune._si_str, n, &nb, NULL) || nb != n)
1315 return;
1316 newsi->_si_commune._si_str[n] = '\0';
1317 si = newsi;
1318 }
1319
1320 pinfo pi (si->si_pid);
1321 if (pi)
1322 new cygthread (commune_process, size, si, "commune");
1323 }
1324
1325 /* Add a packet to the beginning of the queue.
1326 Should only be called from signal thread. */
1327 void
1328 pending_signals::add (sigpacket& pack)
1329 {
1330 sigpacket *se;
1331
1332 se = sigs + pack.si.si_signo;
1333 if (se->si.si_signo)
1334 return;
1335 *se = pack;
1336 se->next = start.next;
1337 start.next = se;
1338 }
1339
1340 /* Process signals by waiting for signal data to arrive in a pipe.
1341 Set a completion event if one was specified. */
1342 static void WINAPI
1343 wait_sig (VOID *)
1344 {
1345 _sig_tls = &_my_tls;
1346 bool sig_held = false;
1347
1348 sigproc_printf ("entering ReadFile loop, my_readsig %p, my_sendsig %p",
1349 my_readsig, my_sendsig);
1350
1351 hntdll = GetModuleHandle ("ntdll.dll");
1352
1353 for (;;)
1354 {
1355 DWORD nb;
1356 sigpacket pack = {};
1357 if (sigq.retry)
1358 pack.si.si_signo = __SIGFLUSH;
1359 else if (!ReadFile (my_readsig, &pack, sizeof (pack), &nb, NULL))
1360 Sleep (INFINITE); /* Assume were exiting. Never exit this thread */
1361 else if (nb != sizeof (pack) || !pack.si.si_signo)
1362 {
1363 system_printf ("garbled signal pipe data nb %u, sig %d", nb, pack.si.si_signo);
1364 continue;
1365 }
1366
1367 sigq.retry = false;
1368 /* Don't process signals when we start exiting */
1369 if (exit_state > ES_EXIT_STARTING && pack.si.si_signo > 0)
1370 goto skip_process_signal;
1371
1372 sigset_t dummy_mask;
1373 threadlist_t *tl_entry;
1374 if (!pack.mask)
1375 {
1376 tl_entry = cygheap->find_tls (_main_tls);
1377 dummy_mask = _main_tls->sigmask;
1378 cygheap->unlock_tls (tl_entry);
1379 pack.mask = &dummy_mask;
1380 }
1381
1382 sigpacket *q;
1383 q = &sigq.start;
1384 bool clearwait;
1385 clearwait = false;
1386 switch (pack.si.si_signo)
1387 {
1388 case __SIGCOMMUNE:
1389 talktome (&pack.si);
1390 break;
1391 case __SIGSTRACE:
1392 strace.activate (false);
1393 break;
1394 case __SIGPENDING:
1395 {
1396 unsigned bit;
1397
1398 *pack.mask = 0;
1399 tl_entry = cygheap->find_tls (pack.sigtls);
1400 while ((q = q->next))
1401 {
1402 /* Skip thread-specific signals for other threads. */
1403 if (q->sigtls && pack.sigtls != q->sigtls)
1404 continue;
1405 if (pack.sigtls->sigmask & (bit = SIGTOMASK (q->si.si_signo)))
1406 *pack.mask |= bit;
1407 }
1408 cygheap->unlock_tls (tl_entry);
1409 }
1410 break;
1411 case __SIGHOLD:
1412 sig_held = true;
1413 break;
1414 case __SIGSETPGRP:
1415 init_console_handler (true);
1416 break;
1417 case __SIGTHREADEXIT:
1418 {
1419 /* Serialize thread exit as the thread exit code can be interpreted
1420 as the process exit code in some cases when racing with
1421 ExitProcess/TerminateProcess.
1422 So, wait for the thread which sent this signal to exit, then
1423 release the process lock which it held and close it's handle.
1424 See cgf-000017 in DevNotes for more details.
1425 */
1426 HANDLE h = (HANDLE) pack.si.si_cyg;
1427 DWORD res = WaitForSingleObject (h, 5000);
1428 lock_process::force_release (pack.sigtls);
1429 ForceCloseHandle1 (h, exit_thread);
1430 if (res != WAIT_OBJECT_0)
1431 {
1432 #ifdef DEBUGGING
1433 try_to_debug();
1434 #endif
1435 system_printf ("WaitForSingleObject(%p) for thread exit returned %u", h, res);
1436 }
1437 }
1438 break;
1439 default: /* Normal (positive) signal */
1440 if (pack.si.si_signo < 0)
1441 sig_clear (-pack.si.si_signo);
1442 else
1443 sigq.add (pack);
1444 fallthrough;
1445 case __SIGNOHOLD:
1446 sig_held = false;
1447 fallthrough;
1448 case __SIGFLUSH:
1449 case __SIGFLUSHFAST:
1450 if (!sig_held)
1451 {
1452 sigpacket *qnext;
1453 /* Check the queue for signals. There will always be at least one
1454 thing on the queue if this was a valid signal. */
1455 while ((qnext = q->next))
1456 {
1457 if (qnext->si.si_signo && qnext->process () <= 0)
1458 q = qnext;
1459 else
1460 {
1461 q->next = qnext->next;
1462 qnext->si.si_signo = 0;
1463 }
1464 }
1465 /* At least one signal still queued? The event is used in select
1466 only, and only to decide if WFMO should wake up in case a
1467 signalfd is waiting via select/poll for being ready to read a
1468 pending signal. This method wakes up all threads hanging in
1469 select and having a signalfd, as soon as a pending signal is
1470 available, but it's certainly better than constant polling. */
1471 if (sigq.start.next)
1472 SetEvent (my_pendingsigs_evt);
1473 else
1474 ResetEvent (my_pendingsigs_evt);
1475 if (pack.si.si_signo == SIGCHLD)
1476 clearwait = true;
1477 }
1478 break;
1479 }
1480 if (clearwait && !have_execed)
1481 proc_subproc (PROC_CLEARWAIT, 0);
1482 skip_process_signal:
1483 if (pack.wakeup)
1484 {
1485 sigproc_printf ("signalling pack.wakeup %p", pack.wakeup);
1486 SetEvent (pack.wakeup);
1487 }
1488 }
1489 }
This page took 0.158849 seconds and 5 git commands to generate.