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