Cygwin: pipe: do short writes only once in nonblocking case too
[newlib-cygwin.git] / winsup / cygwin / fhandler / pipe.cc
blob852076ccc4e86e2d950ea1ce3d9ce4aef9fff349
1 /* fhandler_pipe.cc: pipes for Cygwin.
3 This file is part of Cygwin.
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. */
9 #include "winsup.h"
10 #include <stdlib.h>
11 #include <sys/socket.h>
12 #include "cygerrno.h"
13 #include "security.h"
14 #include "path.h"
15 #include "fhandler.h"
16 #include "select.h"
17 #include "dtable.h"
18 #include "cygheap.h"
19 #include "pinfo.h"
20 #include "shared_info.h"
21 #include "tls_pbuf.h"
22 #include "sigproc.h"
23 #include <assert.h>
25 /* This is only to be used for writing. When reading,
26 STATUS_PIPE_EMPTY simply means there's no data to be read. */
27 #define STATUS_PIPE_IS_CLOSED(status) \
28 ({ NTSTATUS _s = (status); \
29 _s == STATUS_PIPE_CLOSING \
30 || _s == STATUS_PIPE_BROKEN \
31 || _s == STATUS_PIPE_EMPTY; })
33 fhandler_pipe_fifo::fhandler_pipe_fifo ()
34 : fhandler_base (), pipe_buf_size (DEFAULT_PIPEBUFSIZE)
39 fhandler_pipe::fhandler_pipe ()
40 : fhandler_pipe_fifo (), popen_pid (0)
42 need_fork_fixup (true);
45 /* The following function is intended for fhandler_pipe objects
46 created by the second version of fhandler_pipe::create below. See
47 the comment preceding the latter.
49 In addition to setting the blocking mode of the pipe handle, it
50 also sets the pipe's read mode to byte_stream unconditionally. */
51 void
52 fhandler_pipe::set_pipe_non_blocking (bool nonblocking)
54 NTSTATUS status;
55 IO_STATUS_BLOCK io;
56 FILE_PIPE_INFORMATION fpi;
58 fpi.ReadMode = FILE_PIPE_BYTE_STREAM_MODE;
59 fpi.CompletionMode = nonblocking ? FILE_PIPE_COMPLETE_OPERATION
60 : FILE_PIPE_QUEUE_OPERATION;
61 status = NtSetInformationFile (get_handle (), &io, &fpi, sizeof fpi,
62 FilePipeInformation);
63 if (!NT_SUCCESS (status))
64 debug_printf ("NtSetInformationFile(FilePipeInformation): %y", status);
67 int
68 fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode, int64_t uniq_id)
70 /* FIXME: Have to clean this up someday
71 FIXME: Do we have to check for both !get_win32_name() and
72 !*get_win32_name()? */
73 if ((!get_win32_name () || !*get_win32_name ()) && get_name ())
75 char *d;
76 const char *s;
77 char *hold_normalized_name = (char *) alloca (strlen (get_name ()) + 1);
78 for (s = get_name (), d = hold_normalized_name; *s; s++, d++)
79 if (*s == '/')
80 *d = '\\';
81 else
82 *d = *s;
83 *d = '\0';
84 set_name (hold_normalized_name);
87 bool opened_properly = a & FILE_CREATE_PIPE_INSTANCE;
88 a &= ~FILE_CREATE_PIPE_INSTANCE;
89 fhandler_base::init (f, a, mode);
90 close_on_exec (mode & O_CLOEXEC);
91 set_ino (uniq_id);
92 set_unique_id (uniq_id | !!(mode & GENERIC_WRITE));
93 if (opened_properly)
94 /* Set read pipe always nonblocking to allow signal handling
95 even with FILE_SYNCHRONOUS_IO_NONALERT. */
96 set_pipe_non_blocking (get_device () == FH_PIPER ?
97 true : is_nonblocking ());
99 /* Store pipe name to path_conv pc for query_hdl check */
100 if (get_dev () == FH_PIPEW)
102 UNICODE_STRING name;
103 WCHAR pipename_buf[MAX_PATH];
104 __small_swprintf (pipename_buf, L"%S%S-%u-pipe-nt-%p",
105 &ro_u_npfs, &cygheap->installation_key,
106 GetCurrentProcessId (), unique_id >> 32);
107 name.Length = wcslen (pipename_buf) * sizeof (WCHAR);
108 name.MaximumLength = sizeof (pipename_buf);
109 name.Buffer = pipename_buf;
110 pc.set_nt_native_path (&name);
113 return 1;
116 extern "C" int sscanf (const char *, const char *, ...);
119 fhandler_pipe::open (int flags, mode_t mode)
121 HANDLE proc, nio_hdl = NULL;
122 int64_t uniq_id;
123 fhandler_pipe *fh = NULL, *fhr = NULL, *fhw = NULL;
124 size_t size;
125 int pid, rwflags = (flags & O_ACCMODE);
126 bool inh;
127 bool got_one = false;
129 if (sscanf (get_name (), "/proc/%d/fd/pipe:[%llu]",
130 &pid, (long long *) &uniq_id) < 2)
132 set_errno (ENOENT);
133 return 0;
135 if (pid == myself->pid)
137 cygheap_fdenum cfd (true);
138 while (cfd.next () >= 0)
140 /* Windows doesn't allow to copy a pipe HANDLE with another access
141 mode. So we check for read and write side of pipe and try to
142 find the one matching the requested access mode. */
143 if (cfd->get_unique_id () == uniq_id)
144 got_one = true;
145 else if (cfd->get_unique_id () == uniq_id + 1)
146 got_one = true;
147 else
148 continue;
149 if ((rwflags == O_RDONLY && !(cfd->get_access () & GENERIC_READ))
150 || (rwflags == O_WRONLY && !(cfd->get_access () & GENERIC_WRITE)))
151 continue;
152 copy_from (cfd);
153 set_handle (NULL);
154 pc.close_conv_handle ();
155 if (!cfd->dup (this, flags))
156 return 1;
157 return 0;
159 /* Found the pipe but access mode didn't match? EACCES.
160 Otherwise ENOENT */
161 set_errno (got_one ? EACCES : ENOENT);
162 return 0;
165 pinfo p (pid);
166 if (!p)
168 set_errno (ESRCH);
169 return 0;
171 if (!(proc = OpenProcess (PROCESS_DUP_HANDLE, false, p->dwProcessId)))
173 __seterrno ();
174 return 0;
176 fhr = p->pipe_fhandler (uniq_id, size);
177 if (fhr && rwflags == O_RDONLY)
178 fh = fhr;
179 else
181 fhw = p->pipe_fhandler (uniq_id + 1, size);
182 if (fhw && rwflags == O_WRONLY)
183 fh = fhw;
185 if (!fh)
187 /* Too bad, but Windows only allows the same access mode when dup'ing
188 the pipe. */
189 set_errno (fhr || fhw ? EACCES : ENOENT);
190 goto out;
192 inh = !(flags & O_CLOEXEC);
193 if (!DuplicateHandle (proc, fh->get_handle (), GetCurrentProcess (),
194 &nio_hdl, 0, inh, DUPLICATE_SAME_ACCESS))
196 __seterrno ();
197 goto out;
199 init (nio_hdl, fh->get_access (), mode & O_TEXT ?: O_BINARY,
200 fh->get_plain_ino ());
201 cfree (fh);
202 CloseHandle (proc);
203 return 1;
204 out:
205 if (nio_hdl)
206 CloseHandle (nio_hdl);
207 if (fh)
208 free (fh);
209 if (proc)
210 CloseHandle (proc);
211 return 0;
214 bool
215 fhandler_pipe::open_setup (int flags)
217 bool read_mtx_created = false;
219 if (!fhandler_base::open_setup (flags))
220 goto err;
221 if (get_dev () == FH_PIPER && !read_mtx)
223 SECURITY_ATTRIBUTES *sa = sec_none_cloexec (flags);
224 read_mtx = CreateMutex (sa, FALSE, NULL);
225 if (read_mtx)
226 read_mtx_created = true;
227 else
229 debug_printf ("CreateMutex read_mtx failed: %E");
230 goto err;
233 if (!hdl_cnt_mtx)
235 SECURITY_ATTRIBUTES *sa = sec_none_cloexec (flags);
236 hdl_cnt_mtx = CreateMutex (sa, FALSE, NULL);
237 if (!hdl_cnt_mtx)
239 debug_printf ("CreateMutex hdl_cnt_mtx failed: %E");
240 goto err_close_read_mtx;
243 return true;
245 err_close_read_mtx:
246 if (read_mtx_created)
247 CloseHandle (read_mtx);
248 err:
249 return false;
252 off_t
253 fhandler_pipe::lseek (off_t offset, int whence)
255 debug_printf ("(%D, %d)", offset, whence);
256 set_errno (ESPIPE);
257 return -1;
261 fhandler_pipe::fadvise (off_t offset, off_t length, int advice)
263 return ESPIPE;
267 fhandler_pipe::fallocate (int mode, off_t offset, off_t length)
269 return (mode & __FALLOC_FL_TRUNCATE) ? EINVAL : ESPIPE;
272 char *
273 fhandler_pipe::get_proc_fd_name (char *buf)
275 __small_sprintf (buf, "pipe:[%U]", get_plain_ino ());
276 return buf;
279 void
280 fhandler_pipe::release_select_sem (const char *from)
282 LONG n_release;
283 if (get_dev () == FH_PIPER) /* Number of select() and writer */
284 n_release = get_obj_handle_count (select_sem)
285 - get_obj_handle_count (read_mtx);
286 else /* Number of select() call and reader */
287 n_release = get_obj_handle_count (select_sem)
288 - get_obj_handle_count (get_handle ());
289 debug_printf("%s(%s) release %d", from,
290 get_dev () == FH_PIPER ? "PIPER" : "PIPEW", n_release);
291 if (n_release)
292 ReleaseSemaphore (select_sem, n_release, NULL);
295 void
296 fhandler_pipe::raw_read (void *ptr, size_t& len)
298 size_t nbytes = 0;
299 NTSTATUS status = STATUS_SUCCESS;
300 IO_STATUS_BLOCK io;
301 ULONGLONG t0 = GetTickCount64 (); /* Init timer */
302 const ULONGLONG t0_threshold = 20;
304 if (!len)
305 return;
307 DWORD timeout = is_nonblocking () ? 0 : INFINITE;
308 DWORD waitret = cygwait (read_mtx, timeout);
309 switch (waitret)
311 case WAIT_OBJECT_0:
312 break;
313 case WAIT_TIMEOUT:
314 set_errno (EAGAIN);
315 len = (size_t) -1;
316 return;
317 case WAIT_SIGNALED:
318 set_errno (EINTR);
319 len = (size_t) -1;
320 return;
321 case WAIT_CANCELED:
322 pthread::static_cancel_self ();
323 /* NOTREACHED */
324 default:
325 /* Should not reach here. */
326 __seterrno ();
327 len = (size_t) -1;
328 return;
330 while (nbytes < len)
332 ULONG_PTR nbytes_now = 0;
333 ULONG len1 = (ULONG) (len - nbytes);
334 DWORD select_sem_timeout = 0;
336 FILE_PIPE_LOCAL_INFORMATION fpli;
337 status = NtQueryInformationFile (get_handle (), &io,
338 &fpli, sizeof (fpli),
339 FilePipeLocalInformation);
340 if (NT_SUCCESS (status))
342 if (fpli.ReadDataAvailable == 0 && nbytes != 0)
343 break;
345 else if (nbytes != 0)
346 break;
347 status = NtReadFile (get_handle (), NULL, NULL, NULL, &io, ptr,
348 len1, NULL, NULL);
349 if (isclosed ()) /* A signal handler might have closed the fd. */
351 set_errno (EBADF);
352 nbytes = (size_t) -1;
354 else if (NT_SUCCESS (status) || status == STATUS_BUFFER_OVERFLOW)
356 nbytes_now = io.Information;
357 ptr = ((char *) ptr) + nbytes_now;
358 nbytes += nbytes_now;
359 if (select_sem && nbytes_now > 0)
360 release_select_sem ("raw_read");
362 else
364 /* Some errors are not really errors. Detect such cases here. */
365 switch (status)
367 case STATUS_END_OF_FILE:
368 case STATUS_PIPE_BROKEN:
369 /* This is really EOF. */
370 break;
371 case STATUS_PIPE_LISTENING:
372 case STATUS_PIPE_EMPTY:
373 if (nbytes != 0)
374 break;
375 if (is_nonblocking ())
377 set_errno (EAGAIN);
378 nbytes = (size_t) -1;
379 break;
381 /* If the pipe is a non-cygwin pipe, select_sem trick
382 does not work. As a result, the following cygwait()
383 will return only after timeout occurs. This causes
384 performance degradation. However, setting timeout
385 to zero causes high CPU load. So, set timeout to
386 non-zero only when select_sem is valid or pipe is
387 not ready to read for more than t0_threshold.
388 This prevents both the performance degradation and
389 the high CPU load. */
390 if (select_sem || GetTickCount64 () - t0 > t0_threshold)
391 select_sem_timeout = 1;
392 waitret = cygwait (select_sem, select_sem_timeout);
393 if (waitret == WAIT_CANCELED)
394 pthread::static_cancel_self ();
395 else if (waitret == WAIT_SIGNALED)
397 set_errno (EINTR);
398 nbytes = (size_t) -1;
399 break;
401 continue;
402 default:
403 __seterrno_from_nt_status (status);
404 nbytes = (size_t) -1;
405 break;
409 if ((nbytes_now == 0 && !NT_SUCCESS (status))
410 || status == STATUS_BUFFER_OVERFLOW)
411 break;
413 ReleaseMutex (read_mtx);
414 len = nbytes;
417 bool
418 fhandler_pipe::reader_closed ()
420 if (!query_hdl)
421 return false;
422 WaitForSingleObject (hdl_cnt_mtx, INFINITE);
423 int n_reader = get_obj_handle_count (query_hdl);
424 int n_writer = get_obj_handle_count (get_handle ());
425 ReleaseMutex (hdl_cnt_mtx);
426 return n_reader == n_writer;
429 ssize_t
430 fhandler_pipe_fifo::raw_write (const void *ptr, size_t len)
432 size_t nbytes = 0;
433 ULONG chunk;
434 NTSTATUS status = STATUS_SUCCESS;
435 IO_STATUS_BLOCK io;
436 HANDLE evt;
437 bool short_write_once = false;
439 if (!len)
440 return 0;
442 if (reader_closed ())
444 set_errno (EPIPE);
445 raise (SIGPIPE);
446 return -1;
449 if (len <= pipe_buf_size || pipe_buf_size == 0)
450 chunk = len;
451 else if (is_nonblocking ())
452 chunk = len = pipe_buf_size;
453 else
454 chunk = pipe_buf_size;
456 if (!(evt = CreateEvent (NULL, false, false, NULL)))
458 __seterrno ();
459 return -1;
462 /* Write in chunks, accumulating a total. If there's an error, just
463 return the accumulated total unless the first write fails, in
464 which case return -1. */
465 while (nbytes < len)
467 ULONG_PTR nbytes_now = 0;
468 size_t left = len - nbytes;
469 ULONG len1;
470 DWORD waitret = WAIT_OBJECT_0;
472 if (left > chunk)
473 len1 = chunk;
474 else
475 len1 = (ULONG) left;
477 /* NtWriteFile returns success with # of bytes written == 0 if writing
478 on a non-blocking pipe fails because the pipe buffer doesn't have
479 sufficient space.
481 POSIX requires
482 - A write request for {PIPE_BUF} or fewer bytes shall have the
483 following effect: if there is sufficient space available in the
484 pipe, write() shall transfer all the data and return the number
485 of bytes requested. Otherwise, write() shall transfer no data and
486 return -1 with errno set to [EAGAIN].
488 - A write request for more than {PIPE_BUF} bytes shall cause one
489 of the following:
491 - When at least one byte can be written, transfer what it can and
492 return the number of bytes written. When all data previously
493 written to the pipe is read, it shall transfer at least {PIPE_BUF}
494 bytes.
496 - When no data can be written, transfer no data, and return -1 with
497 errno set to [EAGAIN]. */
498 while (len1 > 0)
500 status = NtWriteFile (get_handle (), evt, NULL, NULL, &io,
501 (PVOID) ptr, len1, NULL, NULL);
502 if (status == STATUS_PENDING)
506 /* To allow constant reader_closed() checking even if the
507 signal has been set up with SA_RESTART, we're handling
508 the signal here --> cw_sig_eintr. */
509 waitret = cygwait (evt, (DWORD) 0, cw_cancel | cw_sig_eintr);
510 /* Break out if no SA_RESTART. */
511 if (waitret == WAIT_SIGNALED
512 && !_my_tls.call_signal_handler ())
513 break;
514 if (reader_closed ())
516 CancelIo (get_handle ());
517 set_errno (EPIPE);
518 raise (SIGPIPE);
519 goto out;
521 else
522 cygwait (select_sem, 10, cw_cancel);
523 /* If we got a timeout in the blocking case, and we already
524 did a short write, we got a signal in the previous loop. */
525 if (waitret == WAIT_TIMEOUT && short_write_once)
527 waitret = WAIT_SIGNALED;
528 break;
531 /* Loop in case of blocking write or SA_RESTART */
532 while (waitret == WAIT_TIMEOUT || waitret == WAIT_SIGNALED);
533 /* If io.Status is STATUS_CANCELLED after CancelIo, IO has
534 actually been cancelled and io.Information contains the
535 number of bytes processed so far.
536 Otherwise IO has been finished regulary and io.Status
537 contains valid success or error information. */
538 CancelIo (get_handle ());
539 if (waitret == WAIT_SIGNALED && io.Status != STATUS_CANCELLED)
540 waitret = WAIT_OBJECT_0;
542 if (waitret == WAIT_CANCELED)
543 status = STATUS_THREAD_CANCELED;
544 else if (waitret == WAIT_SIGNALED)
545 status = STATUS_THREAD_SIGNALED;
546 else if (waitret == WAIT_TIMEOUT && io.Status == STATUS_CANCELLED)
547 status = STATUS_SUCCESS;
548 else
549 status = io.Status;
551 if (status != STATUS_THREAD_SIGNALED && !NT_SUCCESS (status))
552 break;
553 if (io.Information > 0 || len <= PIPE_BUF || short_write_once)
554 break;
555 /* Independent of being blocking or non-blocking, if we're here,
556 the pipe has less space than requested. If the pipe is a
557 non-Cygwin pipe, just try the old strategy of trying a half
558 write. If the pipe has at
559 least PIPE_BUF bytes available, try to write all matching
560 PIPE_BUF sized blocks. If it's less than PIPE_BUF, try
561 the next less power of 2 bytes. This is not really the Linux
562 strategy because Linux is filling the pages of a pipe buffer
563 in a very implementation-defined way we can't emulate, but it
564 resembles it closely enough to get useful results. */
565 ssize_t avail = pipe_data_available (-1, this, get_handle (),
566 PDA_WRITE);
567 if (avail < 1) /* error or pipe closed */
568 break;
569 if (avail > len1) /* somebody read from the pipe */
570 avail = len1;
571 if (avail == 1) /* 1 byte left or non-Cygwin pipe */
572 len1 >>= 1;
573 else if (avail >= PIPE_BUF)
574 len1 = avail & ~(PIPE_BUF - 1);
575 else
576 len1 = 1 << (31 - __builtin_clzl (avail));
577 short_write_once = true;
579 if (isclosed ()) /* A signal handler might have closed the fd. */
581 if (waitret == WAIT_OBJECT_0)
582 set_errno (EBADF);
583 else
584 __seterrno ();
586 else if (NT_SUCCESS (status)
587 || status == STATUS_THREAD_CANCELED
588 || status == STATUS_THREAD_SIGNALED)
590 nbytes_now = io.Information;
591 ptr = ((char *) ptr) + nbytes_now;
592 nbytes += nbytes_now;
593 if (select_sem && nbytes_now > 0)
594 release_select_sem ("raw_write");
595 /* 0 bytes returned? EAGAIN. See above. */
596 if (NT_SUCCESS (status) && nbytes == 0)
597 set_errno (EAGAIN);
599 else if (STATUS_PIPE_IS_CLOSED (status))
601 set_errno (EPIPE);
602 raise (SIGPIPE);
604 else
605 __seterrno_from_nt_status (status);
607 if (nbytes_now == 0 || short_write_once)
608 break;
610 out:
611 CloseHandle (evt);
612 if (status == STATUS_THREAD_SIGNALED && nbytes == 0)
613 set_errno (EINTR);
614 else if (status == STATUS_THREAD_CANCELED)
615 pthread::static_cancel_self ();
616 return nbytes ?: -1;
619 void
620 fhandler_pipe::set_close_on_exec (bool val)
622 fhandler_base::set_close_on_exec (val);
623 if (read_mtx)
624 set_no_inheritance (read_mtx, val);
625 if (select_sem)
626 set_no_inheritance (select_sem, val);
627 if (query_hdl)
628 set_no_inheritance (query_hdl, val);
629 set_no_inheritance (hdl_cnt_mtx, val);
632 void
633 fhandler_pipe::fixup_after_fork (HANDLE parent)
635 fork_fixup (parent, hdl_cnt_mtx, "hdl_cnt_mtx");
636 WaitForSingleObject (hdl_cnt_mtx, INFINITE);
637 if (read_mtx)
638 fork_fixup (parent, read_mtx, "read_mtx");
639 if (select_sem)
640 fork_fixup (parent, select_sem, "select_sem");
641 if (query_hdl)
642 fork_fixup (parent, query_hdl, "query_hdl");
643 if (query_hdl_close_req_evt)
644 fork_fixup (parent, query_hdl_close_req_evt, "query_hdl_close_req_evt");
646 fhandler_base::fixup_after_fork (parent);
647 ReleaseMutex (hdl_cnt_mtx);
650 void
651 fhandler_pipe::fixup_after_exec ()
653 /* Set read pipe itself always non-blocking for cygwin process.
654 Blocking/non-blocking is simulated in raw_read(). For write
655 pipe, follow is_nonblocking(). */
656 bool mode = get_device () == FH_PIPEW ? is_nonblocking () : true;
657 set_pipe_non_blocking (mode);
658 fhandler_base::fixup_after_exec ();
662 fhandler_pipe::dup (fhandler_base *child, int flags)
664 fhandler_pipe *ftp = (fhandler_pipe *) child;
665 ftp->set_popen_pid (0);
667 int res = 0;
668 WaitForSingleObject (hdl_cnt_mtx, INFINITE);
669 if (fhandler_base::dup (child, flags))
670 res = -1;
671 else if (read_mtx &&
672 !DuplicateHandle (GetCurrentProcess (), read_mtx,
673 GetCurrentProcess (), &ftp->read_mtx,
674 0, !(flags & O_CLOEXEC), DUPLICATE_SAME_ACCESS))
676 __seterrno ();
677 ftp->close ();
678 res = -1;
680 else if (select_sem &&
681 !DuplicateHandle (GetCurrentProcess (), select_sem,
682 GetCurrentProcess (), &ftp->select_sem,
683 0, !(flags & O_CLOEXEC), DUPLICATE_SAME_ACCESS))
685 __seterrno ();
686 ftp->close ();
687 res = -1;
689 else if (query_hdl &&
690 !DuplicateHandle (GetCurrentProcess (), query_hdl,
691 GetCurrentProcess (), &ftp->query_hdl,
692 0, !(flags & O_CLOEXEC), DUPLICATE_SAME_ACCESS))
694 __seterrno ();
695 ftp->close ();
696 res = -1;
698 else if (!DuplicateHandle (GetCurrentProcess (), hdl_cnt_mtx,
699 GetCurrentProcess (), &ftp->hdl_cnt_mtx,
700 0, !(flags & O_CLOEXEC), DUPLICATE_SAME_ACCESS))
702 __seterrno ();
703 ftp->close ();
704 res = -1;
706 else if (query_hdl_close_req_evt &&
707 !DuplicateHandle (GetCurrentProcess (), query_hdl_close_req_evt,
708 GetCurrentProcess (),
709 &ftp->query_hdl_close_req_evt,
710 0, !(flags & O_CLOEXEC), DUPLICATE_SAME_ACCESS))
712 __seterrno ();
713 ftp->close ();
714 res = -1;
716 ReleaseMutex (hdl_cnt_mtx);
718 debug_printf ("res %d", res);
719 return res;
723 fhandler_pipe::close ()
725 if (select_sem)
727 release_select_sem ("close");
728 CloseHandle (select_sem);
730 if (read_mtx)
731 CloseHandle (read_mtx);
732 WaitForSingleObject (hdl_cnt_mtx, INFINITE);
733 if (query_hdl)
734 CloseHandle (query_hdl);
735 if (query_hdl_close_req_evt)
736 CloseHandle (query_hdl_close_req_evt);
737 int ret = fhandler_base::close ();
738 ReleaseMutex (hdl_cnt_mtx);
739 CloseHandle (hdl_cnt_mtx);
740 if (query_hdl_proc)
741 CloseHandle (query_hdl_proc);
742 return ret;
745 #define PIPE_INTRO "\\\\.\\pipe\\cygwin-"
747 /* Create a pipe, and return handles to the read and write ends,
748 just like CreatePipe, but ensure that the write end permits
749 FILE_READ_ATTRIBUTES access, on later versions of win32 where
750 this is supported. This access is needed by NtQueryInformationFile,
751 which is used to implement select and nonblocking writes.
752 Note that the return value is either 0 or GetLastError,
753 unlike CreatePipe, which returns a bool for success or failure. */
754 DWORD
755 fhandler_pipe::create (LPSECURITY_ATTRIBUTES sa_ptr, PHANDLE r, PHANDLE w,
756 DWORD psize, const char *name, DWORD open_mode,
757 int64_t *unique_id)
759 /* Default to error. */
760 if (r)
761 *r = NULL;
762 if (w)
763 *w = NULL;
765 /* Ensure that there is enough pipe buffer space for atomic writes. */
766 if (!psize)
767 psize = DEFAULT_PIPEBUFSIZE;
769 char pipename[MAX_PATH];
770 size_t len = __small_sprintf (pipename, PIPE_INTRO "%S-",
771 &cygheap->installation_key);
772 DWORD pipe_mode = PIPE_READMODE_BYTE | PIPE_REJECT_REMOTE_CLIENTS;
773 if (!name)
774 pipe_mode |= pipe_byte ? PIPE_TYPE_BYTE : PIPE_TYPE_MESSAGE;
775 else
776 pipe_mode |= PIPE_TYPE_MESSAGE;
778 if (!name || (open_mode & PIPE_ADD_PID))
780 len += __small_sprintf (pipename + len, "%u-", GetCurrentProcessId ());
781 open_mode &= ~PIPE_ADD_PID;
784 if (name)
785 len += __small_sprintf (pipename + len, "%s", name);
787 open_mode |= PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE;
789 /* Retry CreateNamedPipe as long as the pipe name is in use.
790 Retrying will probably never be necessary, but we want
791 to be as robust as possible. */
792 DWORD err = 0;
793 while (r && !*r)
795 static volatile ULONG pipe_unique_id;
796 if (!name)
798 LONG id = InterlockedIncrement ((LONG *) &pipe_unique_id);
799 __small_sprintf (pipename + len, "pipe-%p", id);
800 if (unique_id)
801 *unique_id = ((int64_t) id << 32 | GetCurrentProcessId ());
804 debug_printf ("name %s, size %u, mode %s", pipename, psize,
805 (pipe_mode & PIPE_TYPE_MESSAGE)
806 ? "PIPE_TYPE_MESSAGE" : "PIPE_TYPE_BYTE");
808 /* Use CreateNamedPipe instead of CreatePipe, because the latter
809 returns a write handle that does not permit FILE_READ_ATTRIBUTES
810 access, on versions of win32 earlier than WinXP SP2.
811 CreatePipe also stupidly creates a full duplex pipe, which is
812 a waste, since only a single direction is actually used.
813 It's important to only allow a single instance, to ensure that
814 the pipe was not created earlier by some other process, even if
815 the pid has been reused.
817 Note that the write side of the pipe is opened as PIPE_TYPE_MESSAGE.
818 This *seems* to more closely mimic Linux pipe behavior and is
819 definitely required for pty handling since fhandler_pty_master
820 writes to the pipe in chunks, terminated by newline when CANON mode
821 is specified. */
822 *r = CreateNamedPipe (pipename, open_mode, pipe_mode, 1, psize,
823 psize, NMPWAIT_USE_DEFAULT_WAIT, sa_ptr);
825 if (*r != INVALID_HANDLE_VALUE)
827 debug_printf ("pipe read handle %p", *r);
828 err = 0;
829 break;
832 err = GetLastError ();
833 switch (err)
835 case ERROR_PIPE_BUSY:
836 /* The pipe is already open with compatible parameters.
837 Pick a new name and retry. */
838 debug_printf ("pipe busy", !name ? ", retrying" : "");
839 if (!name)
840 *r = NULL;
841 break;
842 case ERROR_ACCESS_DENIED:
843 /* The pipe is already open with incompatible parameters.
844 Pick a new name and retry. */
845 debug_printf ("pipe access denied%s", !name ? ", retrying" : "");
846 if (!name)
847 *r = NULL;
848 break;
849 default:
851 err = GetLastError ();
852 debug_printf ("failed, %E");
857 if (err)
859 *r = NULL;
860 return err;
863 if (!w)
864 debug_printf ("pipe write handle NULL");
865 else
867 debug_printf ("CreateFile: name %s", pipename);
869 /* Open the named pipe for writing.
870 Be sure to permit FILE_READ_ATTRIBUTES access. */
871 DWORD access = GENERIC_WRITE | FILE_READ_ATTRIBUTES;
872 if ((open_mode & PIPE_ACCESS_DUPLEX) == PIPE_ACCESS_DUPLEX)
873 access |= GENERIC_READ | FILE_WRITE_ATTRIBUTES;
874 *w = CreateFile (pipename, access, 0, sa_ptr, OPEN_EXISTING,
875 open_mode & FILE_FLAG_OVERLAPPED, 0);
877 if (!*w || *w == INVALID_HANDLE_VALUE)
879 /* Failure. */
880 DWORD err = GetLastError ();
881 debug_printf ("CreateFile failed, r %p, %E", r);
882 if (r)
883 CloseHandle (*r);
884 *w = NULL;
885 return err;
888 debug_printf ("pipe write handle %p", *w);
891 /* Success. */
892 return 0;
895 inline static bool
896 is_running_as_service (void)
898 return check_token_membership (well_known_service_sid)
899 || cygheap->user.saved_sid () == well_known_system_sid;
902 /* The next version of fhandler_pipe::create used to call the previous
903 version. But the read handle created by the latter doesn't have
904 FILE_WRITE_ATTRIBUTES access unless the pipe is created with
905 PIPE_ACCESS_DUPLEX, and it doesn't seem possible to add that access
906 right. This causes set_pipe_non_blocking to fail.
908 To fix this we will define a helper function 'nt_create' that is
909 similar to the above fhandler_pipe::create but uses
910 NtCreateNamedPipeFile instead of CreateNamedPipe; this gives more
911 flexibility in setting the access rights. We will use this helper
912 function in the version of fhandler_pipe::create below, which
913 suffices for all of our uses of set_pipe_non_blocking. For
914 simplicity, nt_create will omit the 'open_mode' and 'name'
915 parameters, which aren't needed for our purposes. */
917 static int nt_create (LPSECURITY_ATTRIBUTES, HANDLE &, HANDLE &, DWORD,
918 int64_t *);
921 fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode)
923 HANDLE r, w;
924 SECURITY_ATTRIBUTES *sa = sec_none_cloexec (mode);
925 int res = -1;
926 int64_t unique_id;
928 int ret = nt_create (sa, r, w, psize, &unique_id);
929 if (ret)
931 __seterrno_from_win_error (ret);
932 goto out;
934 if ((fhs[0] = (fhandler_pipe *) build_fh_dev (*piper_dev)) == NULL)
935 goto err_close_rw_handle;
936 if ((fhs[1] = (fhandler_pipe *) build_fh_dev (*pipew_dev)) == NULL)
937 goto err_delete_fhs0;
938 mode |= mode & O_TEXT ?: O_BINARY;
939 fhs[0]->init (r, FILE_CREATE_PIPE_INSTANCE | GENERIC_READ, mode, unique_id);
940 fhs[1]->init (w, FILE_CREATE_PIPE_INSTANCE | GENERIC_WRITE, mode, unique_id);
942 /* For the read side of the pipe, add a mutex. See raw_read for the
943 usage. */
944 fhs[0]->read_mtx = CreateMutexW (sa, FALSE, NULL);
945 if (!fhs[0]->read_mtx)
946 goto err_delete_fhs1;
948 fhs[0]->select_sem = CreateSemaphore (sa, 0, INT32_MAX, NULL);
949 if (!fhs[0]->select_sem)
950 goto err_close_read_mtx;
951 if (!DuplicateHandle (GetCurrentProcess (), fhs[0]->select_sem,
952 GetCurrentProcess (), &fhs[1]->select_sem,
953 0, sa->bInheritHandle, DUPLICATE_SAME_ACCESS))
954 goto err_close_select_sem0;
956 if (is_running_as_service () &&
957 !DuplicateHandle (GetCurrentProcess (), r,
958 GetCurrentProcess (), &fhs[1]->query_hdl,
959 FILE_READ_DATA, sa->bInheritHandle, 0))
960 goto err_close_select_sem1;
962 fhs[0]->hdl_cnt_mtx = CreateMutexW (sa, FALSE, NULL);
963 if (!fhs[0]->hdl_cnt_mtx)
964 goto err_close_query_hdl;
965 if (!DuplicateHandle (GetCurrentProcess (), fhs[0]->hdl_cnt_mtx,
966 GetCurrentProcess (), &fhs[1]->hdl_cnt_mtx,
967 0, sa->bInheritHandle, DUPLICATE_SAME_ACCESS))
968 goto err_close_hdl_cnt_mtx0;
970 if (fhs[1]->query_hdl)
972 fhs[1]->query_hdl_close_req_evt = CreateEvent (sa, TRUE, FALSE, NULL);
973 if (!fhs[1]->query_hdl_close_req_evt)
974 goto err_close_hdl_cnt_mtx1;
977 res = 0;
978 goto out;
980 err_close_hdl_cnt_mtx1:
981 CloseHandle (fhs[1]->hdl_cnt_mtx);
982 err_close_hdl_cnt_mtx0:
983 CloseHandle (fhs[0]->hdl_cnt_mtx);
984 err_close_query_hdl:
985 if (fhs[1]->query_hdl)
986 CloseHandle (fhs[1]->query_hdl);
987 err_close_select_sem1:
988 CloseHandle (fhs[1]->select_sem);
989 err_close_select_sem0:
990 CloseHandle (fhs[0]->select_sem);
991 err_close_read_mtx:
992 CloseHandle (fhs[0]->read_mtx);
993 err_delete_fhs1:
994 delete fhs[1];
995 err_delete_fhs0:
996 delete fhs[0];
997 err_close_rw_handle:
998 NtClose (r);
999 NtClose (w);
1000 out:
1001 debug_printf ("%R = pipe([%p, %p], %d, %y)",
1002 res, fhs[0], fhs[1], psize, mode);
1003 return res;
1006 static int
1007 nt_create (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE &r, HANDLE &w,
1008 DWORD psize, int64_t *unique_id)
1010 NTSTATUS status;
1011 HANDLE npfsh;
1012 ACCESS_MASK access;
1013 OBJECT_ATTRIBUTES attr;
1014 IO_STATUS_BLOCK io;
1015 LARGE_INTEGER timeout;
1017 /* Default to error. */
1018 r = NULL;
1019 w = NULL;
1021 status = fhandler_base::npfs_handle (npfsh);
1022 if (!NT_SUCCESS (status))
1024 __seterrno_from_nt_status (status);
1025 return GetLastError ();
1028 /* Ensure that there is enough pipe buffer space for atomic writes. */
1029 if (!psize)
1030 psize = DEFAULT_PIPEBUFSIZE;
1032 UNICODE_STRING pipename;
1033 WCHAR pipename_buf[MAX_PATH];
1034 size_t len = __small_swprintf (pipename_buf, L"%S-%u-",
1035 &cygheap->installation_key,
1036 GetCurrentProcessId ());
1038 access = GENERIC_READ | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE;
1039 access |= FILE_WRITE_EA; /* Add this right as a marker of cygwin read pipe */
1041 ULONG pipe_type = pipe_byte ? FILE_PIPE_BYTE_STREAM_TYPE
1042 : FILE_PIPE_MESSAGE_TYPE;
1044 /* Retry NtCreateNamedPipeFile as long as the pipe name is in use.
1045 Retrying will probably never be necessary, but we want
1046 to be as robust as possible. */
1047 DWORD err = 0;
1048 while (!r)
1050 static volatile ULONG pipe_unique_id;
1051 LONG id = InterlockedIncrement ((LONG *) &pipe_unique_id);
1052 __small_swprintf (pipename_buf + len, L"pipe-nt-%p", id);
1053 if (unique_id)
1054 *unique_id = ((int64_t) id << 32 | GetCurrentProcessId ());
1056 debug_printf ("name %W, size %u, mode %s", pipename_buf, psize,
1057 (pipe_type & FILE_PIPE_MESSAGE_TYPE)
1058 ? "PIPE_TYPE_MESSAGE" : "PIPE_TYPE_BYTE");
1060 RtlInitUnicodeString (&pipename, pipename_buf);
1062 InitializeObjectAttributes (&attr, &pipename,
1063 sa_ptr->bInheritHandle ? OBJ_INHERIT : 0,
1064 npfsh, sa_ptr->lpSecurityDescriptor);
1066 timeout.QuadPart = -500000;
1067 /* Set FILE_SYNCHRONOUS_IO_NONALERT flag so that native
1068 C# programs work with cygwin pipe. */
1069 status = NtCreateNamedPipeFile (&r, access, &attr, &io,
1070 FILE_SHARE_READ | FILE_SHARE_WRITE,
1071 FILE_CREATE,
1072 FILE_SYNCHRONOUS_IO_NONALERT, pipe_type,
1073 FILE_PIPE_BYTE_STREAM_MODE,
1074 0, 1, psize, psize, &timeout);
1076 if (NT_SUCCESS (status))
1078 debug_printf ("pipe read handle %p", r);
1079 err = 0;
1080 break;
1083 switch (status)
1085 case STATUS_PIPE_BUSY:
1086 case STATUS_INSTANCE_NOT_AVAILABLE:
1087 case STATUS_PIPE_NOT_AVAILABLE:
1088 /* The pipe is already open with compatible parameters.
1089 Pick a new name and retry. */
1090 debug_printf ("pipe busy, retrying");
1091 r = NULL;
1092 break;
1093 case STATUS_ACCESS_DENIED:
1094 /* The pipe is already open with incompatible parameters.
1095 Pick a new name and retry. */
1096 debug_printf ("pipe access denied, retrying");
1097 r = NULL;
1098 break;
1099 default:
1101 __seterrno_from_nt_status (status);
1102 err = GetLastError ();
1103 debug_printf ("failed, %E");
1104 r = NULL;
1109 if (err)
1111 r = NULL;
1112 return err;
1115 debug_printf ("NtOpenFile: name %S", &pipename);
1117 access = GENERIC_WRITE | FILE_READ_ATTRIBUTES | SYNCHRONIZE;
1118 status = NtOpenFile (&w, access, &attr, &io, 0, 0);
1119 if (!NT_SUCCESS (status))
1121 DWORD err = GetLastError ();
1122 debug_printf ("NtOpenFile failed, r %p, %E", r);
1123 if (r)
1124 NtClose (r);
1125 w = NULL;
1126 return err;
1129 /* Success. */
1130 return 0;
1133 /* Called by dtable::init_std_file_from_handle for stdio handles
1134 inherited from non-Cygwin processes. */
1135 void
1136 fhandler_pipe::set_pipe_buf_size ()
1138 NTSTATUS status;
1139 IO_STATUS_BLOCK io;
1140 FILE_PIPE_LOCAL_INFORMATION fpli;
1142 status = NtQueryInformationFile (get_handle (), &io, &fpli, sizeof fpli,
1143 FilePipeLocalInformation);
1144 if (NT_SUCCESS (status))
1145 pipe_buf_size = fpli.InboundQuota;
1149 fhandler_pipe::ioctl (unsigned int cmd, void *p)
1151 int n;
1153 switch (cmd)
1155 case FIONREAD:
1156 if (get_device () == FH_PIPEW)
1158 set_errno (EINVAL);
1159 return -1;
1161 if (!PeekNamedPipe (get_handle (), NULL, 0, NULL, (DWORD *) &n, NULL))
1163 __seterrno ();
1164 return -1;
1166 break;
1167 default:
1168 return fhandler_base::ioctl (cmd, p);
1169 break;
1171 *(int *) p = n;
1172 return 0;
1176 fhandler_pipe::fcntl (int cmd, intptr_t arg)
1178 if (cmd != F_SETFL)
1179 return fhandler_base::fcntl (cmd, arg);
1181 const bool was_nonblocking = is_nonblocking ();
1182 int res = fhandler_base::fcntl (cmd, arg);
1183 const bool now_nonblocking = is_nonblocking ();
1184 /* Do not set blocking mode for read pipe to allow signal handling
1185 even with FILE_SYNCHRONOUS_IO_NONALERT. */
1186 if (now_nonblocking != was_nonblocking && get_device () != FH_PIPER)
1187 set_pipe_non_blocking (now_nonblocking);
1188 return res;
1192 fhandler_pipe::fstat (struct stat *buf)
1194 int ret = fhandler_base::fstat (buf);
1195 if (!ret)
1197 buf->st_dev = FH_PIPE;
1198 if (!(buf->st_ino = get_plain_ino ()))
1199 sscanf (get_name (), "/proc/%*d/fd/pipe:[%llu]",
1200 (long long *) &buf->st_ino);
1202 return ret;
1206 fhandler_pipe::fstatvfs (struct statvfs *sfs)
1208 set_errno (EBADF);
1209 return -1;
1212 HANDLE
1213 fhandler_pipe::temporary_query_hdl ()
1215 if (get_dev () != FH_PIPEW)
1216 return NULL;
1218 ULONG len;
1219 NTSTATUS status;
1220 tmp_pathbuf tp;
1221 OBJECT_NAME_INFORMATION *ntfn = (OBJECT_NAME_INFORMATION *) tp.w_get ();
1223 UNICODE_STRING *name = pc.get_nt_native_path (NULL);
1225 /* Try process handle opened and pipe handle value cached first
1226 in order to reduce overhead. */
1227 if (query_hdl_proc && query_hdl_value)
1229 HANDLE h;
1230 if (!DuplicateHandle (query_hdl_proc, query_hdl_value,
1231 GetCurrentProcess (), &h, FILE_READ_DATA, 0, 0))
1232 goto cache_err;
1233 /* Check name */
1234 status = NtQueryObject (h, ObjectNameInformation, ntfn, 65536, &len);
1235 if (!NT_SUCCESS (status) || !ntfn->Name.Buffer)
1236 goto hdl_err;
1237 if (RtlEqualUnicodeString (name, &ntfn->Name, FALSE))
1238 return h;
1239 hdl_err:
1240 CloseHandle (h);
1241 cache_err:
1242 CloseHandle (query_hdl_proc);
1243 query_hdl_proc = NULL;
1244 query_hdl_value = NULL;
1247 if (name->Length == 0 || name->Buffer == NULL)
1248 return NULL; /* Non cygwin pipe? */
1249 return get_query_hdl_per_process (ntfn); /* Since Win8 */
1252 HANDLE
1253 fhandler_pipe::get_query_hdl_per_process (OBJECT_NAME_INFORMATION *ntfn)
1255 winpids pids ((DWORD) 0);
1257 /* In most cases, it is faster to check the processes in reverse order. */
1258 for (LONG i = (LONG) pids.npids - 1; i >= 0; i--)
1260 NTSTATUS status;
1261 ULONG len;
1263 /* Non-cygwin app may call ReadFile() for empty pipe, which makes
1264 NtQueryObject() for ObjectNameInformation block. Therefore, do
1265 not try to get query_hdl for non-cygwin apps. */
1266 _pinfo *p = pids[i];
1267 if (!p || ISSTATE (p, PID_NOTCYGWIN))
1268 continue;
1270 HANDLE proc = OpenProcess (PROCESS_DUP_HANDLE
1271 | PROCESS_QUERY_INFORMATION,
1272 0, p->dwProcessId);
1273 if (!proc)
1274 continue;
1276 /* Retrieve process handles */
1277 DWORD n_handle = 256;
1278 PPROCESS_HANDLE_SNAPSHOT_INFORMATION phi;
1281 DWORD nbytes = 2 * sizeof (ULONG_PTR) +
1282 n_handle * sizeof (PROCESS_HANDLE_TABLE_ENTRY_INFO);
1283 phi = (PPROCESS_HANDLE_SNAPSHOT_INFORMATION)
1284 HeapAlloc (GetProcessHeap (), 0, nbytes);
1285 if (!phi)
1286 goto close_proc;
1287 /* NtQueryInformationProcess can return STATUS_SUCCESS with
1288 invalid handle data for certain processes. See
1289 https://github.com/processhacker/processhacker/blob/05f5e9fa477dcaa1709d9518170d18e1b3b8330d/phlib/native.c#L5754.
1290 We need to ensure that NumberOfHandles is zero in this
1291 case to avoid a crash in the for loop below. */
1292 phi->NumberOfHandles = 0;
1293 status = NtQueryInformationProcess (proc, ProcessHandleInformation,
1294 phi, nbytes, &len);
1295 if (NT_SUCCESS (status))
1296 break;
1297 HeapFree (GetProcessHeap (), 0, phi);
1298 n_handle *= 2;
1300 while (n_handle < (1L<<20) && status == STATUS_INFO_LENGTH_MISMATCH);
1301 if (!NT_SUCCESS (status))
1302 goto close_proc;
1304 /* Sanity check in case Microsoft changes
1305 NtQueryInformationProcess and the initialization of
1306 NumberOfHandles above is no longer sufficient. */
1307 assert (phi->NumberOfHandles <= n_handle);
1308 for (ULONG j = 0; j < phi->NumberOfHandles; j++)
1310 /* Check for the peculiarity of cygwin read pipe */
1311 const ULONG access = FILE_READ_DATA | FILE_READ_EA
1312 | FILE_WRITE_EA /* marker */
1313 | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES
1314 | READ_CONTROL | SYNCHRONIZE;
1315 if (phi->Handles[j].GrantedAccess != access)
1316 continue;
1318 /* Retrieve handle */
1319 HANDLE h = (HANDLE)(intptr_t) phi->Handles[j].HandleValue;
1320 BOOL res = DuplicateHandle (proc, h, GetCurrentProcess (), &h,
1321 FILE_READ_DATA, 0, 0);
1322 if (!res)
1323 continue;
1325 /* Check object name */
1326 status = NtQueryObject (h, ObjectNameInformation,
1327 ntfn, 65536, &len);
1328 if (!NT_SUCCESS (status) || !ntfn->Name.Buffer)
1329 goto close_handle;
1330 if (RtlEqualUnicodeString (pc.get_nt_native_path (),
1331 &ntfn->Name, FALSE))
1333 query_hdl_proc = proc;
1334 query_hdl_value = (HANDLE)(intptr_t) phi->Handles[j].HandleValue;
1335 HeapFree (GetProcessHeap (), 0, phi);
1336 return h;
1338 close_handle:
1339 CloseHandle (h);
1341 HeapFree (GetProcessHeap (), 0, phi);
1342 close_proc:
1343 CloseHandle (proc);
1345 return NULL;
1348 void
1349 fhandler_pipe::spawn_worker (int fileno_stdin, int fileno_stdout,
1350 int fileno_stderr)
1352 bool need_send_noncygchld_sig = false;
1354 /* spawn_worker() is called from spawn.cc only when non-cygwin app
1355 is started. Set pipe mode blocking for the non-cygwin process. */
1356 int fd;
1357 cygheap_fdenum cfd (false);
1358 while ((fd = cfd.next ()) >= 0)
1359 if (cfd->get_dev () == FH_PIPEW
1360 && (fd == fileno_stdout || fd == fileno_stderr))
1362 fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
1363 pipe->set_pipe_non_blocking (false);
1365 /* Setup for query_ndl stuff. Read the comment below. */
1366 if (pipe->request_close_query_hdl ())
1367 need_send_noncygchld_sig = true;
1369 else if (cfd->get_dev () == FH_PIPER && fd == fileno_stdin)
1371 fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
1372 pipe->set_pipe_non_blocking (false);
1375 /* If multiple writers including non-cygwin app exist, the non-cygwin
1376 app cannot detect pipe closure on the read side when the pipe is
1377 created by system account or the pipe creator is running as service.
1378 This is because query_hdl which is held in write side also is a read
1379 end of the pipe, so the pipe is still alive for the non-cygwin app
1380 even after the reader is closed.
1382 To avoid this problem, let all processes in the same process
1383 group close query_hdl using internal signal __SIGNONCYGCHLD when
1384 non-cygwin app is started. */
1385 if (need_send_noncygchld_sig)
1387 tty_min dummy_tty;
1388 dummy_tty.ntty = (fh_devices) myself->ctty;
1389 dummy_tty.pgid = myself->pgid;
1390 tty_min *t = cygwin_shared->tty.get_cttyp ();
1391 if (!t) /* If tty is not allocated, use dummy_tty instead. */
1392 t = &dummy_tty;
1393 /* Emit __SIGNONCYGCHLD to let all processes in the
1394 process group close query_hdl. */
1395 t->kill_pgrp (__SIGNONCYGCHLD);