1 /* pipe.cc: pipe for Cygwin.
3 Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
12 /* FIXME: Should this really be fhandler_pipe.cc? */
17 #include <sys/socket.h>
27 #include "cygthread.h"
30 static unsigned pipecount;
31 static const NO_COPY char pipeid_fmt[] = "stupid_pipe.%u.%u";
33 fhandler_pipe::fhandler_pipe ()
34 : fhandler_base (), guard (NULL), broken_pipe (false), writepipe_exists(0),
39 extern "C" int sscanf (const char *, const char *, ...);
42 fhandler_pipe::open (int flags, mode_t mode)
44 HANDLE proc, pipe_hdl, nio_hdl = NULL, nwrp_hdl = NULL;
45 fhandler_pipe *fh = NULL;
47 int pid, rwflags = (flags & O_ACCMODE);
54 sscanf (get_name (), "/proc/%d/fd/pipe:[%d]", &pid, (int *) &pipe_hdl);
55 if (pid == myself->pid)
58 while (cfd.next () >= 0)
60 if (cfd->get_handle () != pipe_hdl)
62 if ((rwflags == O_RDONLY && !(cfd->get_access () & GENERIC_READ))
63 || (rwflags == O_WRONLY && !(cfd->get_access () & GENERIC_WRITE)))
82 if (!(proc = OpenProcess (PROCESS_DUP_HANDLE, false, p->dwProcessId)))
87 if (!(fh = p->pipe_fhandler (pipe_hdl, size)) || !size)
92 /* Too bad, but Windows only allows the same access mode when dup'ing
94 if ((rwflags == O_RDONLY && !(fh->get_access () & GENERIC_READ))
95 || (rwflags == O_WRONLY && !(fh->get_access () & GENERIC_WRITE)))
100 if (!DuplicateHandle (proc, pipe_hdl, hMainProc, &nio_hdl,
101 0, false, DUPLICATE_SAME_ACCESS))
106 if (fh->writepipe_exists
107 && !DuplicateHandle (proc, fh->writepipe_exists,
108 hMainProc, &nwrp_hdl,
109 0, false, DUPLICATE_SAME_ACCESS))
116 create_read_state (2);
117 need_fork_fixup (true);
118 ProtectHandle1 (read_state, read_state);
120 if (fh->get_guard ())
121 create_guard ((flags & O_NOINHERIT) ? &sec_none_nih : &sec_none);
122 init (nio_hdl, fh->get_access (), mode & O_TEXT ?: O_BINARY);
123 writepipe_exists = nwrp_hdl;
124 if (flags & O_NOINHERIT)
125 close_on_exec (true);
126 uninterruptible_io (fh->uninterruptible_io ());
132 CloseHandle (nwrp_hdl);
134 CloseHandle (nio_hdl);
143 fhandler_pipe::lseek (_off64_t offset, int whence)
145 debug_printf ("(%d, %d)", offset, whence);
151 fhandler_pipe::set_close_on_exec (bool val)
153 fhandler_base::set_close_on_exec (val);
155 set_no_inheritance (guard, val);
156 if (writepipe_exists)
157 set_no_inheritance (writepipe_exists, val);
160 char *fhandler_pipe::get_proc_fd_name (char *buf)
162 __small_sprintf (buf, "pipe:[%d]", get_handle ());
174 read_pipe (void *arg)
176 pipeargs *pi = (pipeargs *) arg;
177 pi->fh->fhandler_base::read (pi->ptr, *pi->len);
182 fhandler_pipe::read (void *in_ptr, size_t& in_len)
188 pipeargs pi = {dynamic_cast<fhandler_base *>(this), in_ptr, &in_len};
189 ResetEvent (read_state);
190 cygthread *th = new cygthread (read_pipe, &pi, "read_pipe");
191 if (th->detach (read_state) && !in_len)
192 in_len = (size_t) -1; /* received a signal */
194 (void) ReleaseMutex (guard);
199 fhandler_pipe::close ()
203 if (writepipe_exists)
204 CloseHandle (writepipe_exists);
208 // FIXME is this vfork_cleanup test right? Is it responsible for some of
209 // the strange pipe behavior that has been reported in the cygwin mailing
211 if (read_state && !cygheap->fdtab.in_vfork_cleanup ())
213 ForceCloseHandle (read_state);
216 CloseHandle (get_handle ());
217 set_io_handle (NULL);
223 fhandler_pipe::hit_eof ()
231 __small_sprintf (buf, pipeid_fmt, orig_pid, id);
232 if ((ev = OpenEvent (EVENT_ALL_ACCESS, FALSE, buf)))
234 debug_printf ("%s %p", buf, ev);
239 fhandler_pipe::fixup_after_exec ()
243 create_read_state (2);
244 ProtectHandle (read_state);
249 fhandler_pipe::fixup_after_fork (HANDLE parent)
251 fhandler_base::fixup_after_fork (parent);
253 fork_fixup (parent, guard, "guard");
254 if (writepipe_exists)
255 fork_fixup (parent, writepipe_exists, "guard");
260 fhandler_pipe::dup (fhandler_base *child)
263 fhandler_pipe *ftp = (fhandler_pipe *) child;
264 ftp->guard = ftp->writepipe_exists = ftp->read_state = NULL;
268 res = fhandler_base::dup (child);
273 /* FIXME: This leaks handles in the failing condition */
276 else if (!DuplicateHandle (hMainProc, guard, hMainProc, &ftp->guard, 0, 1,
277 DUPLICATE_SAME_ACCESS))
279 debug_printf ("couldn't duplicate guard %p, %E", guard);
283 if (writepipe_exists == NULL)
284 ftp->writepipe_exists = NULL;
285 else if (!DuplicateHandle (hMainProc, writepipe_exists, hMainProc,
286 &ftp->writepipe_exists, 0, 1,
287 DUPLICATE_SAME_ACCESS))
289 debug_printf ("couldn't duplicate writepipe_exists %p, %E", writepipe_exists);
293 if (read_state == NULL)
294 ftp->read_state = NULL;
295 else if (!DuplicateHandle (hMainProc, read_state, hMainProc,
296 &ftp->read_state, 0, 0,
297 DUPLICATE_SAME_ACCESS))
299 debug_printf ("couldn't duplicate read_state %p, %E", read_state);
308 CloseHandle (ftp->guard);
309 if (ftp->writepipe_exists)
310 CloseHandle (ftp->writepipe_exists);
312 CloseHandle (ftp->read_state);
317 ftp->orig_pid = orig_pid;
318 VerifyHandle (ftp->guard);
319 VerifyHandle (ftp->writepipe_exists);
320 VerifyHandle (ftp->read_state);
323 debug_printf ("res %d", res);
327 /* Create a pipe, and return handles to the read and write ends,
328 just like CreatePipe, but ensure that the write end permits
329 FILE_READ_ATTRIBUTES access, on later versions of win32 where
330 this is supported. This access is needed by NtQueryInformationFile,
331 which is used to implement select and nonblocking writes.
332 Note that the return value is either NO_ERROR or GetLastError,
333 unlike CreatePipe, which returns a bool for success or failure. */
335 create_selectable_pipe (PHANDLE read_pipe_ptr,
336 PHANDLE write_pipe_ptr,
337 LPSECURITY_ATTRIBUTES sa_ptr,
340 /* Default to error. */
341 *read_pipe_ptr = *write_pipe_ptr = INVALID_HANDLE_VALUE;
343 HANDLE read_pipe = INVALID_HANDLE_VALUE, write_pipe = INVALID_HANDLE_VALUE;
345 /* Ensure that there is enough pipe buffer space for atomic writes. */
346 if (psize < PIPE_BUF)
349 char pipename[CYG_MAX_PATH];
351 /* Retry CreateNamedPipe as long as the pipe name is in use.
352 Retrying will probably never be necessary, but we want
353 to be as robust as possible. */
356 static volatile LONG pipe_unique_id;
358 __small_sprintf (pipename, "\\\\.\\pipe\\cygwin-%d-%ld", myself->pid,
359 InterlockedIncrement ((LONG *) &pipe_unique_id));
361 debug_printf ("CreateNamedPipe: name %s, size %lu", pipename, psize);
363 /* Use CreateNamedPipe instead of CreatePipe, because the latter
364 returns a write handle that does not permit FILE_READ_ATTRIBUTES
365 access, on versions of win32 earlier than WinXP SP2.
366 CreatePipe also stupidly creates a full duplex pipe, which is
367 a waste, since only a single direction is actually used.
368 It's important to only allow a single instance, to ensure that
369 the pipe was not created earlier by some other process, even if
370 the pid has been reused. We avoid FILE_FLAG_FIRST_PIPE_INSTANCE
371 because that is only available for Win2k SP2 and WinXP. */
373 read_pipe = CreateNamedPipe (pipename,
375 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
376 1, /* max instances */
377 psize, /* output buffer size */
378 psize, /* input buffer size */
379 NMPWAIT_USE_DEFAULT_WAIT,
382 DWORD err = GetLastError ();
383 /* Win 95 seems to return NULL instead of INVALID_HANDLE_VALUE */
384 if ((read_pipe || !err) && read_pipe != INVALID_HANDLE_VALUE)
386 debug_printf ("pipe read handle %p", read_pipe);
392 case ERROR_PIPE_BUSY:
393 /* The pipe is already open with compatible parameters.
394 Pick a new name and retry. */
395 debug_printf ("pipe busy, retrying");
397 case ERROR_ACCESS_DENIED:
398 /* The pipe is already open with incompatible parameters.
399 Pick a new name and retry. */
400 debug_printf ("pipe access denied, retrying");
402 case ERROR_CALL_NOT_IMPLEMENTED:
403 /* We are on an older Win9x platform without named pipes.
404 Return an anonymous pipe as the best approximation. */
405 debug_printf ("CreateNamedPipe not implemented, resorting to "
406 "CreatePipe size %lu", psize);
407 if (CreatePipe (read_pipe_ptr, write_pipe_ptr, sa_ptr, psize))
409 debug_printf ("pipe read handle %p", *read_pipe_ptr);
410 debug_printf ("pipe write handle %p", *write_pipe_ptr);
413 err = GetLastError ();
414 debug_printf ("CreatePipe failed, %E");
417 debug_printf ("CreateNamedPipe failed, %E");
423 debug_printf ("CreateFile: name %s", pipename);
425 /* Open the named pipe for writing.
426 Be sure to permit FILE_READ_ATTRIBUTES access. */
427 write_pipe = CreateFile (pipename,
428 GENERIC_WRITE | FILE_READ_ATTRIBUTES,
432 0, /* flags and attributes */
433 0); /* handle to template file */
435 if (write_pipe == INVALID_HANDLE_VALUE)
438 DWORD err = GetLastError ();
439 debug_printf ("CreateFile failed, %E");
440 CloseHandle (read_pipe);
444 debug_printf ("pipe write handle %p", write_pipe);
447 *read_pipe_ptr = read_pipe;
448 *write_pipe_ptr = write_pipe;
453 fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode, bool fifo)
456 SECURITY_ATTRIBUTES *sa = (mode & O_NOINHERIT) ? &sec_none_nih : &sec_none;
460 if ((ret = create_selectable_pipe (&r, &w, sa, psize)) != NO_ERROR)
461 __seterrno_from_win_error (ret);
464 fhs[0] = (fhandler_pipe *) build_fh_dev (*piper_dev);
465 fhs[1] = (fhandler_pipe *) build_fh_dev (*pipew_dev);
467 int binmode = mode & O_TEXT ?: O_BINARY;
468 fhs[0]->init (r, GENERIC_READ, binmode);
469 fhs[1]->init (w, GENERIC_WRITE, binmode);
470 if (mode & O_NOINHERIT)
472 fhs[0]->close_on_exec (true);
473 fhs[1]->close_on_exec (true);
476 fhs[0]->create_read_state (2);
477 fhs[0]->need_fork_fixup (true);
478 ProtectHandle1 (fhs[0]->read_state, read_state);
481 fhs[0]->create_guard (sa);
482 if (wincap.has_unreliable_pipes ())
485 int count = pipecount++; /* FIXME: Should this be InterlockedIncrement? */
486 __small_sprintf (buf, pipeid_fmt, myself->pid, count);
487 fhs[1]->writepipe_exists = CreateEvent (sa, TRUE, FALSE, buf);
488 fhs[0]->orig_pid = myself->pid;
493 syscall_printf ("%d = pipe ([%p, %p], %d, %p)", res, fhs[0], fhs[1], psize, mode);
498 fhandler_pipe::ioctl (unsigned int cmd, void *p)
505 if (get_device () == FH_PIPEW)
510 if (!PeekNamedPipe (get_handle (), NULL, 0, NULL, (DWORD *) &n, NULL))
517 return fhandler_base::ioctl (cmd, p);
524 #define DEFAULT_PIPEBUFSIZE (4 * PIPE_BUF)
527 pipe (int filedes[2])
529 extern DWORD binmode;
530 fhandler_pipe *fhs[2];
531 int res = fhandler_pipe::create (fhs, DEFAULT_PIPEBUFSIZE,
532 (!binmode || binmode == O_BINARY)
533 ? O_BINARY : O_TEXT);
537 cygheap_fdnew fdout (fdin, false);
548 _pipe (int filedes[2], unsigned int psize, int mode)
550 fhandler_pipe *fhs[2];
551 int res = fhandler_pipe::create (fhs, psize, mode);
552 /* This type of pipe is not interruptible so set the appropriate flag. */
556 cygheap_fdnew fdout (fdin, false);
557 fhs[0]->uninterruptible_io (true);