OSDN Git Service

* path.cc (path_conv::check): Leave symlink expansion loop in case
[pf3gnuchains/pf3gnuchains3x.git] / winsup / cygwin / pipe.cc
1 /* pipe.cc: pipe for Cygwin.
2
3    Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4    2005 Red Hat, Inc.
5
6 This file is part of Cygwin.
7
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
10 details. */
11
12 /* FIXME: Should this really be fhandler_pipe.cc? */
13
14 #include "winsup.h"
15 #include <unistd.h>
16 #include <stdlib.h>
17 #include <sys/socket.h>
18 #include <limits.h>
19 #include "cygerrno.h"
20 #include "security.h"
21 #include "path.h"
22 #include "fhandler.h"
23 #include "dtable.h"
24 #include "cygheap.h"
25 #include "thread.h"
26 #include "pinfo.h"
27 #include "cygthread.h"
28 #include "ntdll.h"
29
30 static unsigned pipecount;
31 static const NO_COPY char pipeid_fmt[] = "stupid_pipe.%u.%u";
32
33 fhandler_pipe::fhandler_pipe ()
34   : fhandler_base (), guard (NULL), broken_pipe (false), writepipe_exists(0),
35     orig_pid (0), id (0)
36 {
37 }
38
39 extern "C" int sscanf (const char *, const char *, ...);
40
41 int
42 fhandler_pipe::open (int flags, mode_t mode)
43 {
44   HANDLE proc, pipe_hdl, nio_hdl = NULL, nwrp_hdl = NULL;
45   fhandler_pipe *fh = NULL;
46   size_t size;
47   int pid, rwflags = (flags & O_ACCMODE);
48
49   if (flags & O_CREAT)
50     {
51       set_errno (EACCES);
52       return 0;
53     }
54   sscanf (get_name (), "/proc/%d/fd/pipe:[%d]", &pid, (int *) &pipe_hdl);
55   if (pid == myself->pid)
56     {
57       cygheap_fdenum cfd;
58       while (cfd.next () >= 0)
59         {
60           if (cfd->get_handle () != pipe_hdl)
61             continue;
62           if ((rwflags == O_RDONLY && !(cfd->get_access () & GENERIC_READ))
63               || (rwflags == O_WRONLY && !(cfd->get_access () & GENERIC_WRITE)))
64             {
65               set_errno (EACCES);
66               return 0;
67             }
68           if (!cfd->dup (this))
69             return 1;
70           return 0;
71         }
72       set_errno (ENOENT);
73       return 0;
74     }
75
76   pinfo p (pid);
77   if (!p)
78     {
79       set_errno (ESRCH);
80       return 0;
81     }
82   if (!(proc = OpenProcess (PROCESS_DUP_HANDLE, false, p->dwProcessId)))
83     {
84       __seterrno ();
85       return 0;
86     }
87   if (!(fh = p->pipe_fhandler (pipe_hdl, size)) || !size)
88     {
89       set_errno (ENOENT);
90       goto out;
91     }
92   /* Too bad, but Windows only allows the same access mode when dup'ing
93      the pipe. */
94   if ((rwflags == O_RDONLY && !(fh->get_access () & GENERIC_READ))
95       || (rwflags == O_WRONLY && !(fh->get_access () & GENERIC_WRITE)))
96     {
97       set_errno (EACCES);
98       goto out;
99     }
100   if (!DuplicateHandle (proc, pipe_hdl, hMainProc, &nio_hdl,
101                         0, false, DUPLICATE_SAME_ACCESS))
102     {
103       __seterrno ();
104       goto out;
105     }
106   if (fh->writepipe_exists
107       && !DuplicateHandle (proc, fh->writepipe_exists,
108                            hMainProc, &nwrp_hdl,
109                            0, false, DUPLICATE_SAME_ACCESS))
110     {
111       __seterrno ();
112       goto out;
113     }
114   if (fh->read_state)
115     {
116       create_read_state (2);
117       need_fork_fixup (true);
118       ProtectHandle1 (read_state, read_state);
119     }
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 ());
127   free (fh);
128   CloseHandle (proc);
129   return 1;
130 out:
131   if (nwrp_hdl)
132     CloseHandle (nwrp_hdl);
133   if (nio_hdl)
134     CloseHandle (nio_hdl);
135   if (fh)
136     free (fh);
137   if (proc)
138     CloseHandle (proc);
139   return 0;
140 }
141
142 _off64_t
143 fhandler_pipe::lseek (_off64_t offset, int whence)
144 {
145   debug_printf ("(%d, %d)", offset, whence);
146   set_errno (ESPIPE);
147   return -1;
148 }
149
150 void
151 fhandler_pipe::set_close_on_exec (bool val)
152 {
153   fhandler_base::set_close_on_exec (val);
154   if (guard)
155     set_no_inheritance (guard, val);
156   if (writepipe_exists)
157     set_no_inheritance (writepipe_exists, val);
158 }
159
160 char *fhandler_pipe::get_proc_fd_name (char *buf)
161 {
162   __small_sprintf (buf, "pipe:[%d]", get_handle ());
163   return buf;
164 }
165
166 struct pipeargs
167 {
168   fhandler_base *fh;
169   void *ptr;
170   size_t *len;
171 };
172
173 static DWORD WINAPI
174 read_pipe (void *arg)
175 {
176   pipeargs *pi = (pipeargs *) arg;
177   pi->fh->fhandler_base::read (pi->ptr, *pi->len);
178   return 0;
179 }
180
181 void __stdcall
182 fhandler_pipe::read (void *in_ptr, size_t& in_len)
183 {
184   if (broken_pipe)
185     in_len = 0;
186   else
187     {
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 */
193     }
194   (void) ReleaseMutex (guard);
195   return;
196 }
197
198 int
199 fhandler_pipe::close ()
200 {
201   if (guard)
202     CloseHandle (guard);
203   if (writepipe_exists)
204     CloseHandle (writepipe_exists);
205 #ifndef NEWVFORK
206   if (read_state)
207 #else
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
210   // list?
211   if (read_state && !cygheap->fdtab.in_vfork_cleanup ())
212 #endif
213     ForceCloseHandle (read_state);
214   if (get_handle ())
215     {
216       CloseHandle (get_handle ());
217       set_io_handle (NULL);
218     }
219   return 0;
220 }
221
222 bool
223 fhandler_pipe::hit_eof ()
224 {
225   char buf[80];
226   HANDLE ev;
227   if (broken_pipe)
228     return 1;
229   if (!orig_pid)
230     return false;
231   __small_sprintf (buf, pipeid_fmt, orig_pid, id);
232   if ((ev = OpenEvent (EVENT_ALL_ACCESS, FALSE, buf)))
233     CloseHandle (ev);
234   debug_printf ("%s %p", buf, ev);
235   return ev == NULL;
236 }
237
238 void
239 fhandler_pipe::fixup_after_exec ()
240 {
241   if (read_state)
242     {
243       create_read_state (2);
244       ProtectHandle (read_state);
245     }
246 }
247
248 void
249 fhandler_pipe::fixup_after_fork (HANDLE parent)
250 {
251   fhandler_base::fixup_after_fork (parent);
252   if (guard)
253     fork_fixup (parent, guard, "guard");
254   if (writepipe_exists)
255     fork_fixup (parent, writepipe_exists, "guard");
256   fixup_after_exec ();
257 }
258
259 int
260 fhandler_pipe::dup (fhandler_base *child)
261 {
262   int res = -1;
263   fhandler_pipe *ftp = (fhandler_pipe *) child;
264   ftp->guard = ftp->writepipe_exists = ftp->read_state = NULL;
265
266   if (get_handle ())
267     {
268       res = fhandler_base::dup (child);
269       if (res)
270         goto err;
271     }
272
273   /* FIXME: This leaks handles in the failing condition */
274   if (guard == NULL)
275     ftp->guard = NULL;
276   else if (!DuplicateHandle (hMainProc, guard, hMainProc, &ftp->guard, 0, 1,
277                              DUPLICATE_SAME_ACCESS))
278     {
279       debug_printf ("couldn't duplicate guard %p, %E", guard);
280       goto err;
281     }
282
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))
288     {
289       debug_printf ("couldn't duplicate writepipe_exists %p, %E", writepipe_exists);
290       goto err;
291     }
292
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))
298     {
299       debug_printf ("couldn't duplicate read_state %p, %E", read_state);
300       goto err;
301     }
302
303   res = 0;
304   goto out;
305
306 err:
307   if (ftp->guard)
308     CloseHandle (ftp->guard);
309   if (ftp->writepipe_exists)
310     CloseHandle (ftp->writepipe_exists);
311   if (ftp->read_state)
312     CloseHandle (ftp->read_state);
313   goto leave;
314
315 out:
316   ftp->id = id;
317   ftp->orig_pid = orig_pid;
318   VerifyHandle (ftp->guard);
319   VerifyHandle (ftp->writepipe_exists);
320   VerifyHandle (ftp->read_state);
321
322 leave:
323   debug_printf ("res %d", res);
324   return res;
325 }
326
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.  */
334 static int
335 create_selectable_pipe (PHANDLE read_pipe_ptr,
336                         PHANDLE write_pipe_ptr,
337                         LPSECURITY_ATTRIBUTES sa_ptr,
338                         DWORD psize)
339 {
340   /* Default to error. */
341   *read_pipe_ptr = *write_pipe_ptr = INVALID_HANDLE_VALUE;
342
343   HANDLE read_pipe = INVALID_HANDLE_VALUE, write_pipe = INVALID_HANDLE_VALUE;
344
345   /* Ensure that there is enough pipe buffer space for atomic writes.  */
346   if (psize < PIPE_BUF)
347     psize = PIPE_BUF;
348
349   char pipename[CYG_MAX_PATH];
350
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.  */
354   while (1)
355     {
356       static volatile LONG pipe_unique_id;
357
358       __small_sprintf (pipename, "\\\\.\\pipe\\cygwin-%d-%ld", myself->pid,
359                        InterlockedIncrement ((LONG *) &pipe_unique_id));
360
361       debug_printf ("CreateNamedPipe: name %s, size %lu", pipename, psize);
362
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.  */
372       SetLastError (0);
373       read_pipe = CreateNamedPipe (pipename,
374                                    PIPE_ACCESS_INBOUND,
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,
380                                    sa_ptr);
381
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)
385         {
386           debug_printf ("pipe read handle %p", read_pipe);
387           break;
388         }
389
390       switch (err)
391         {
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");
396           continue;
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");
401           continue;
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))
408             {
409               debug_printf ("pipe read handle %p", *read_pipe_ptr);
410               debug_printf ("pipe write handle %p", *write_pipe_ptr);
411               return NO_ERROR;
412             }
413           err = GetLastError ();
414           debug_printf ("CreatePipe failed, %E");
415           return err;
416         default:
417           debug_printf ("CreateNamedPipe failed, %E");
418           return err;
419         }
420       /* NOTREACHED */
421     }
422
423   debug_printf ("CreateFile: name %s", pipename);
424
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,
429                            0,       /* share mode */
430                            sa_ptr,
431                            OPEN_EXISTING,
432                            0,       /* flags and attributes */
433                            0);      /* handle to template file */
434
435   if (write_pipe == INVALID_HANDLE_VALUE)
436     {
437       /* Failure. */
438       DWORD err = GetLastError ();
439       debug_printf ("CreateFile failed, %E");
440       CloseHandle (read_pipe);
441       return err;
442     }
443
444   debug_printf ("pipe write handle %p", write_pipe);
445
446   /* Success. */
447   *read_pipe_ptr = read_pipe;
448   *write_pipe_ptr = write_pipe;
449   return NO_ERROR;
450 }
451
452 int
453 fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode, bool fifo)
454 {
455   HANDLE r, w;
456   SECURITY_ATTRIBUTES *sa = (mode & O_NOINHERIT) ?  &sec_none_nih : &sec_none;
457   int res = -1;
458   int ret;
459
460   if ((ret = create_selectable_pipe (&r, &w, sa, psize)) != NO_ERROR)
461     __seterrno_from_win_error (ret);
462   else
463     {
464       fhs[0] = (fhandler_pipe *) build_fh_dev (*piper_dev);
465       fhs[1] = (fhandler_pipe *) build_fh_dev (*pipew_dev);
466
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)
471        {
472          fhs[0]->close_on_exec (true);
473          fhs[1]->close_on_exec (true);
474        }
475
476       fhs[0]->create_read_state (2);
477       fhs[0]->need_fork_fixup (true);
478       ProtectHandle1 (fhs[0]->read_state, read_state);
479
480       res = 0;
481       fhs[0]->create_guard (sa);
482       if (wincap.has_unreliable_pipes ())
483         {
484           char buf[80];
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;
489           fhs[0]->id = count;
490         }
491     }
492
493   syscall_printf ("%d = pipe ([%p, %p], %d, %p)", res, fhs[0], fhs[1], psize, mode);
494   return res;
495 }
496
497 int
498 fhandler_pipe::ioctl (unsigned int cmd, void *p)
499 {
500   int n;
501
502   switch (cmd)
503     {
504     case FIONREAD:
505       if (get_device () == FH_PIPEW)
506         {
507           set_errno (EINVAL);
508           return -1;
509         }
510       if (!PeekNamedPipe (get_handle (), NULL, 0, NULL, (DWORD *) &n, NULL))
511         {
512           __seterrno ();
513           return -1;
514         }
515       break;
516     default:
517       return fhandler_base::ioctl (cmd, p);
518       break;
519     }
520   *(int *) p = n;
521   return 0;
522 }
523
524 #define DEFAULT_PIPEBUFSIZE (4 * PIPE_BUF)
525
526 extern "C" int
527 pipe (int filedes[2])
528 {
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);
534   if (res == 0)
535     {
536       cygheap_fdnew fdin;
537       cygheap_fdnew fdout (fdin, false);
538       fdin = fhs[0];
539       fdout = fhs[1];
540       filedes[0] = fdin;
541       filedes[1] = fdout;
542     }
543
544   return res;
545 }
546
547 extern "C" int
548 _pipe (int filedes[2], unsigned int psize, int mode)
549 {
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. */
553   if (!res)
554     {
555       cygheap_fdnew fdin;
556       cygheap_fdnew fdout (fdin, false);
557       fhs[0]->uninterruptible_io (true);
558       fdin = fhs[0];
559       fdout = fhs[1];
560       filedes[0] = fdin;
561       filedes[1] = fdout;
562     }
563
564   return res;
565 }