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
11 #include <sys/socket.h>
20 #include "shared_info.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. */
52 fhandler_pipe::set_pipe_non_blocking (bool nonblocking
)
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
,
63 if (!NT_SUCCESS (status
))
64 debug_printf ("NtSetInformationFile(FilePipeInformation): %y", status
);
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 ())
77 char *hold_normalized_name
= (char *) alloca (strlen (get_name ()) + 1);
78 for (s
= get_name (), d
= hold_normalized_name
; *s
; s
++, d
++)
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
);
92 set_unique_id (uniq_id
| !!(mode
& GENERIC_WRITE
));
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
)
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
);
116 extern "C" int sscanf (const char *, const char *, ...);
119 fhandler_pipe::open (int flags
, mode_t mode
)
121 HANDLE proc
, nio_hdl
= NULL
;
123 fhandler_pipe
*fh
= NULL
, *fhr
= NULL
, *fhw
= NULL
;
125 int pid
, rwflags
= (flags
& O_ACCMODE
);
127 bool got_one
= false;
129 if (sscanf (get_name (), "/proc/%d/fd/pipe:[%llu]",
130 &pid
, (long long *) &uniq_id
) < 2)
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
)
145 else if (cfd
->get_unique_id () == uniq_id
+ 1)
149 if ((rwflags
== O_RDONLY
&& !(cfd
->get_access () & GENERIC_READ
))
150 || (rwflags
== O_WRONLY
&& !(cfd
->get_access () & GENERIC_WRITE
)))
154 pc
.close_conv_handle ();
155 if (!cfd
->dup (this, flags
))
159 /* Found the pipe but access mode didn't match? EACCES.
161 set_errno (got_one
? EACCES
: ENOENT
);
171 if (!(proc
= OpenProcess (PROCESS_DUP_HANDLE
, false, p
->dwProcessId
)))
176 fhr
= p
->pipe_fhandler (uniq_id
, size
);
177 if (fhr
&& rwflags
== O_RDONLY
)
181 fhw
= p
->pipe_fhandler (uniq_id
+ 1, size
);
182 if (fhw
&& rwflags
== O_WRONLY
)
187 /* Too bad, but Windows only allows the same access mode when dup'ing
189 set_errno (fhr
|| fhw
? EACCES
: ENOENT
);
192 inh
= !(flags
& O_CLOEXEC
);
193 if (!DuplicateHandle (proc
, fh
->get_handle (), GetCurrentProcess (),
194 &nio_hdl
, 0, inh
, DUPLICATE_SAME_ACCESS
))
199 init (nio_hdl
, fh
->get_access (), mode
& O_TEXT
?: O_BINARY
,
200 fh
->get_plain_ino ());
206 CloseHandle (nio_hdl
);
215 fhandler_pipe::open_setup (int flags
)
217 bool read_mtx_created
= false;
219 if (!fhandler_base::open_setup (flags
))
221 if (get_dev () == FH_PIPER
&& !read_mtx
)
223 SECURITY_ATTRIBUTES
*sa
= sec_none_cloexec (flags
);
224 read_mtx
= CreateMutex (sa
, FALSE
, NULL
);
226 read_mtx_created
= true;
229 debug_printf ("CreateMutex read_mtx failed: %E");
235 SECURITY_ATTRIBUTES
*sa
= sec_none_cloexec (flags
);
236 hdl_cnt_mtx
= CreateMutex (sa
, FALSE
, NULL
);
239 debug_printf ("CreateMutex hdl_cnt_mtx failed: %E");
240 goto err_close_read_mtx
;
246 if (read_mtx_created
)
247 CloseHandle (read_mtx
);
253 fhandler_pipe::lseek (off_t offset
, int whence
)
255 debug_printf ("(%D, %d)", offset
, whence
);
261 fhandler_pipe::fadvise (off_t offset
, off_t length
, int advice
)
267 fhandler_pipe::fallocate (int mode
, off_t offset
, off_t length
)
269 return (mode
& __FALLOC_FL_TRUNCATE
) ? EINVAL
: ESPIPE
;
273 fhandler_pipe::get_proc_fd_name (char *buf
)
275 __small_sprintf (buf
, "pipe:[%U]", get_plain_ino ());
280 fhandler_pipe::release_select_sem (const char *from
)
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
);
292 ReleaseSemaphore (select_sem
, n_release
, NULL
);
296 fhandler_pipe::raw_read (void *ptr
, size_t& len
)
299 NTSTATUS status
= STATUS_SUCCESS
;
301 ULONGLONG t0
= GetTickCount64 (); /* Init timer */
302 const ULONGLONG t0_threshold
= 20;
307 DWORD timeout
= is_nonblocking () ? 0 : INFINITE
;
308 DWORD waitret
= cygwait (read_mtx
, timeout
);
322 pthread::static_cancel_self ();
325 /* Should not reach here. */
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)
345 else if (nbytes
!= 0)
347 status
= NtReadFile (get_handle (), NULL
, NULL
, NULL
, &io
, ptr
,
349 if (isclosed ()) /* A signal handler might have closed the fd. */
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");
364 /* Some errors are not really errors. Detect such cases here. */
367 case STATUS_END_OF_FILE
:
368 case STATUS_PIPE_BROKEN
:
369 /* This is really EOF. */
371 case STATUS_PIPE_LISTENING
:
372 case STATUS_PIPE_EMPTY
:
375 if (is_nonblocking ())
378 nbytes
= (size_t) -1;
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
)
398 nbytes
= (size_t) -1;
403 __seterrno_from_nt_status (status
);
404 nbytes
= (size_t) -1;
409 if ((nbytes_now
== 0 && !NT_SUCCESS (status
))
410 || status
== STATUS_BUFFER_OVERFLOW
)
413 ReleaseMutex (read_mtx
);
418 fhandler_pipe::reader_closed ()
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
;
430 fhandler_pipe_fifo::raw_write (const void *ptr
, size_t len
)
434 NTSTATUS status
= STATUS_SUCCESS
;
437 bool short_write_once
= false;
442 if (reader_closed ())
449 if (len
<= pipe_buf_size
|| pipe_buf_size
== 0)
451 else if (is_nonblocking ())
452 chunk
= len
= pipe_buf_size
;
454 chunk
= pipe_buf_size
;
456 if (!(evt
= CreateEvent (NULL
, false, false, NULL
)))
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. */
467 ULONG_PTR nbytes_now
= 0;
468 size_t left
= len
- nbytes
;
470 DWORD waitret
= WAIT_OBJECT_0
;
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
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
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}
496 - When no data can be written, transfer no data, and return -1 with
497 errno set to [EAGAIN]. */
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 ())
514 if (reader_closed ())
516 CancelIo (get_handle ());
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
;
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
;
551 if (status
!= STATUS_THREAD_SIGNALED
&& !NT_SUCCESS (status
))
553 if (io
.Information
> 0 || len
<= PIPE_BUF
|| short_write_once
)
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 (),
567 if (avail
< 1) /* error or pipe closed */
569 if (avail
> len1
) /* somebody read from the pipe */
571 if (avail
== 1) /* 1 byte left or non-Cygwin pipe */
573 else if (avail
>= PIPE_BUF
)
574 len1
= avail
& ~(PIPE_BUF
- 1);
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
)
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)
599 else if (STATUS_PIPE_IS_CLOSED (status
))
605 __seterrno_from_nt_status (status
);
607 if (nbytes_now
== 0 || short_write_once
)
612 if (status
== STATUS_THREAD_SIGNALED
&& nbytes
== 0)
614 else if (status
== STATUS_THREAD_CANCELED
)
615 pthread::static_cancel_self ();
620 fhandler_pipe::set_close_on_exec (bool val
)
622 fhandler_base::set_close_on_exec (val
);
624 set_no_inheritance (read_mtx
, val
);
626 set_no_inheritance (select_sem
, val
);
628 set_no_inheritance (query_hdl
, val
);
629 set_no_inheritance (hdl_cnt_mtx
, val
);
633 fhandler_pipe::fixup_after_fork (HANDLE parent
)
635 fork_fixup (parent
, hdl_cnt_mtx
, "hdl_cnt_mtx");
636 WaitForSingleObject (hdl_cnt_mtx
, INFINITE
);
638 fork_fixup (parent
, read_mtx
, "read_mtx");
640 fork_fixup (parent
, select_sem
, "select_sem");
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
);
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);
668 WaitForSingleObject (hdl_cnt_mtx
, INFINITE
);
669 if (fhandler_base::dup (child
, flags
))
672 !DuplicateHandle (GetCurrentProcess (), read_mtx
,
673 GetCurrentProcess (), &ftp
->read_mtx
,
674 0, !(flags
& O_CLOEXEC
), DUPLICATE_SAME_ACCESS
))
680 else if (select_sem
&&
681 !DuplicateHandle (GetCurrentProcess (), select_sem
,
682 GetCurrentProcess (), &ftp
->select_sem
,
683 0, !(flags
& O_CLOEXEC
), DUPLICATE_SAME_ACCESS
))
689 else if (query_hdl
&&
690 !DuplicateHandle (GetCurrentProcess (), query_hdl
,
691 GetCurrentProcess (), &ftp
->query_hdl
,
692 0, !(flags
& O_CLOEXEC
), DUPLICATE_SAME_ACCESS
))
698 else if (!DuplicateHandle (GetCurrentProcess (), hdl_cnt_mtx
,
699 GetCurrentProcess (), &ftp
->hdl_cnt_mtx
,
700 0, !(flags
& O_CLOEXEC
), DUPLICATE_SAME_ACCESS
))
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
))
716 ReleaseMutex (hdl_cnt_mtx
);
718 debug_printf ("res %d", res
);
723 fhandler_pipe::close ()
727 release_select_sem ("close");
728 CloseHandle (select_sem
);
731 CloseHandle (read_mtx
);
732 WaitForSingleObject (hdl_cnt_mtx
, INFINITE
);
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
);
741 CloseHandle (query_hdl_proc
);
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. */
755 fhandler_pipe::create (LPSECURITY_ATTRIBUTES sa_ptr
, PHANDLE r
, PHANDLE w
,
756 DWORD psize
, const char *name
, DWORD open_mode
,
759 /* Default to error. */
765 /* Ensure that there is enough pipe buffer space for atomic writes. */
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
;
774 pipe_mode
|= pipe_byte
? PIPE_TYPE_BYTE
: PIPE_TYPE_MESSAGE
;
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
;
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. */
795 static volatile ULONG pipe_unique_id
;
798 LONG id
= InterlockedIncrement ((LONG
*) &pipe_unique_id
);
799 __small_sprintf (pipename
+ len
, "pipe-%p", 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
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
);
832 err
= GetLastError ();
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" : "");
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" : "");
851 err
= GetLastError ();
852 debug_printf ("failed, %E");
864 debug_printf ("pipe write handle NULL");
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
)
880 DWORD err
= GetLastError ();
881 debug_printf ("CreateFile failed, r %p, %E", r
);
888 debug_printf ("pipe write handle %p", *w
);
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
,
921 fhandler_pipe::create (fhandler_pipe
*fhs
[2], unsigned psize
, int mode
)
924 SECURITY_ATTRIBUTES
*sa
= sec_none_cloexec (mode
);
928 int ret
= nt_create (sa
, r
, w
, psize
, &unique_id
);
931 __seterrno_from_win_error (ret
);
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
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
;
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
);
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
);
992 CloseHandle (fhs
[0]->read_mtx
);
1001 debug_printf ("%R = pipe([%p, %p], %d, %y)",
1002 res
, fhs
[0], fhs
[1], psize
, mode
);
1007 nt_create (LPSECURITY_ATTRIBUTES sa_ptr
, HANDLE
&r
, HANDLE
&w
,
1008 DWORD psize
, int64_t *unique_id
)
1013 OBJECT_ATTRIBUTES attr
;
1015 LARGE_INTEGER timeout
;
1017 /* Default to error. */
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. */
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. */
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
);
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
,
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
);
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");
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");
1101 __seterrno_from_nt_status (status
);
1102 err
= GetLastError ();
1103 debug_printf ("failed, %E");
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
);
1133 /* Called by dtable::init_std_file_from_handle for stdio handles
1134 inherited from non-Cygwin processes. */
1136 fhandler_pipe::set_pipe_buf_size ()
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
)
1156 if (get_device () == FH_PIPEW
)
1161 if (!PeekNamedPipe (get_handle (), NULL
, 0, NULL
, (DWORD
*) &n
, NULL
))
1168 return fhandler_base::ioctl (cmd
, p
);
1176 fhandler_pipe::fcntl (int cmd
, intptr_t arg
)
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
);
1192 fhandler_pipe::fstat (struct stat
*buf
)
1194 int ret
= fhandler_base::fstat (buf
);
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
);
1206 fhandler_pipe::fstatvfs (struct statvfs
*sfs
)
1213 fhandler_pipe::temporary_query_hdl ()
1215 if (get_dev () != FH_PIPEW
)
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
)
1230 if (!DuplicateHandle (query_hdl_proc
, query_hdl_value
,
1231 GetCurrentProcess (), &h
, FILE_READ_DATA
, 0, 0))
1234 status
= NtQueryObject (h
, ObjectNameInformation
, ntfn
, 65536, &len
);
1235 if (!NT_SUCCESS (status
) || !ntfn
->Name
.Buffer
)
1237 if (RtlEqualUnicodeString (name
, &ntfn
->Name
, FALSE
))
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 */
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
--)
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
))
1270 HANDLE proc
= OpenProcess (PROCESS_DUP_HANDLE
1271 | PROCESS_QUERY_INFORMATION
,
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
);
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
,
1295 if (NT_SUCCESS (status
))
1297 HeapFree (GetProcessHeap (), 0, phi
);
1300 while (n_handle
< (1L<<20) && status
== STATUS_INFO_LENGTH_MISMATCH
);
1301 if (!NT_SUCCESS (status
))
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
)
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);
1325 /* Check object name */
1326 status
= NtQueryObject (h
, ObjectNameInformation
,
1328 if (!NT_SUCCESS (status
) || !ntfn
->Name
.Buffer
)
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
);
1341 HeapFree (GetProcessHeap (), 0, phi
);
1349 fhandler_pipe::spawn_worker (int fileno_stdin
, int fileno_stdout
,
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. */
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
)
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. */
1393 /* Emit __SIGNONCYGCHLD to let all processes in the
1394 process group close query_hdl. */
1395 t
->kill_pgrp (__SIGNONCYGCHLD
);