OSDN Git Service

ff42b744d321d485f1d39bbf64aff152d49f9073
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / dtable.cc
1 /* dtable.cc: file descriptor support.
2
3    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4    2005, 2006, 2007, 2008, 2009, 2010, 2011 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 #define  __INSIDE_CYGWIN_NET__
13
14 #include "winsup.h"
15 #include <sys/socket.h>
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <unistd.h>
19 #include <wchar.h>
20
21 #define USE_SYS_TYPES_FD_SET
22 #include <winsock.h>
23 #include "pinfo.h"
24 #include "cygerrno.h"
25 #include "perprocess.h"
26 #include "path.h"
27 #include "fhandler.h"
28 #include "select.h"
29 #include "dtable.h"
30 #include "cygheap.h"
31 #include "tls_pbuf.h"
32 #include "ntdll.h"
33 #include "shared_info.h"
34
35 static const NO_COPY DWORD std_consts[] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
36                                            STD_ERROR_HANDLE};
37
38 static bool handle_to_fn (HANDLE, char *);
39
40 #define WCLEN(x) ((sizeof (x) / sizeof (WCHAR)) - 1)
41 static const char unknown_file[] = "some disk file";
42 static const WCHAR DEV_NULL[] = L"\\Device\\Null";
43 static const WCHAR DEV_SOCKET[] = L"\\Device\\Afd";
44
45 static const WCHAR DEVICE_PREFIX[] = L"\\device\\";
46 static const size_t DEVICE_PREFIX_LEN WCLEN (DEVICE_PREFIX);
47
48 static const WCHAR DEV_NAMED_PIPE[] = L"\\Device\\NamedPipe\\";
49 static const size_t DEV_NAMED_PIPE_LEN = WCLEN (DEV_NAMED_PIPE);
50
51 static const WCHAR DEV_REMOTE[] = L"\\Device\\LanmanRedirector\\";
52 static const size_t DEV_REMOTE_LEN = WCLEN (DEV_REMOTE);
53
54 static const WCHAR DEV_REMOTE1[] = L"\\Device\\WinDfs\\Root\\";
55 static const size_t DEV_REMOTE1_LEN = WCLEN (DEV_REMOTE1);
56
57 /* Set aside space for the table of fds */
58 void
59 dtable_init ()
60 {
61   if (!cygheap->fdtab.size)
62     cygheap->fdtab.extend (NOFILE_INCR);
63 }
64
65 void __stdcall
66 set_std_handle (int fd)
67 {
68   if (fd == 0)
69     SetStdHandle (std_consts[fd], cygheap->fdtab[fd]->get_handle ());
70   else if (fd <= 2)
71     SetStdHandle (std_consts[fd], cygheap->fdtab[fd]->get_output_handle ());
72 }
73
74 int
75 dtable::extend (int howmuch)
76 {
77   int new_size = size + howmuch;
78   fhandler_base **newfds;
79
80   if (howmuch <= 0)
81     return 0;
82
83   if (new_size > OPEN_MAX_MAX)
84     {
85       set_errno (EMFILE);
86       return 0;
87     }
88
89   /* Try to allocate more space for fd table. We can't call realloc ()
90      here to preserve old table if memory allocation fails */
91
92   if (!(newfds = (fhandler_base **) ccalloc (HEAP_ARGV, new_size, sizeof newfds[0])))
93     {
94       debug_printf ("calloc failed");
95       set_errno (ENOMEM);
96       return 0;
97     }
98   if (fds)
99     {
100       memcpy (newfds, fds, size * sizeof (fds[0]));
101       cfree (fds);
102     }
103
104   size = new_size;
105   fds = newfds;
106   debug_printf ("size %d, fds %p", size, fds);
107   return 1;
108 }
109
110 void
111 dtable::get_debugger_info ()
112 {
113   extern bool jit_debug;
114   if (!jit_debug && being_debugged ())
115     {
116       char std[3][sizeof ("/dev/ptyNNNN")];
117       std[0][0] = std[1][0] = std [2][0] = '\0';
118       char buf[sizeof ("cYgstd %x") + 32];
119       sprintf (buf, "cYgstd %x %x %x", (unsigned) &std, sizeof (std[0]), 3);
120       OutputDebugString (buf);
121       for (int i = 0; i < 3; i++)
122         if (std[i][0])
123           {
124             HANDLE h = GetStdHandle (std_consts[i]);
125             fhandler_base *fh = build_fh_name (std[i]);
126             if (!fh)
127               continue;
128             fds[i] = fh;
129             if (!fh->open ((i ? (i == 2 ? O_RDWR : O_WRONLY) : O_RDONLY)
130                            | O_BINARY, 0777))
131               release (i);
132             else
133               {
134                 CloseHandle (h);
135                 /* Copy to Windows' idea of a standard handle, otherwise
136                    we have invalid standard handles when calling Windows
137                    functions (small_printf and strace might suffer, too). */
138                 SetStdHandle (std_consts[i], i ? fh->get_output_handle ()
139                                                : fh->get_handle ());
140               }
141           }
142     }
143 }
144
145 /* Initialize the file descriptor/handle mapping table.
146    This function should only be called when a cygwin function is invoked
147    by a non-cygwin function, i.e., it should only happen very rarely. */
148
149 void
150 dtable::stdio_init ()
151 {
152   /* Set these before trying to output anything from strace.
153      Also, always set them even if we're to pick up our parent's fds
154      in case they're missed.  */
155
156   if (myself->cygstarted || ISSTATE (myself, PID_CYGPARENT))
157     {
158       tty_min *t = cygwin_shared->tty.get_cttyp ();
159       if (t && t->getpgid () == myself->pid && t->is_console)
160         init_console_handler (true);
161       return;
162     }
163
164   HANDLE in = GetStdHandle (STD_INPUT_HANDLE);
165   HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
166   HANDLE err = GetStdHandle (STD_ERROR_HANDLE);
167
168   init_std_file_from_handle (0, in);
169
170   /* STD_ERROR_HANDLE has been observed to be the same as
171      STD_OUTPUT_HANDLE.  We need separate handles (e.g. using pipes
172      to pass data from child to parent).  */
173   /* CV 2008-10-17: Under debugger control, std fd's have been potentially
174      initialized in dtable::get_debugger_info ().  In this case
175      init_std_file_from_handle is a no-op, so, even if out == err we don't
176      want to duplicate the handle since it will be unused. */
177   if (out == err && (!being_debugged () || not_open (2)))
178     {
179       /* Since this code is not invoked for forked tasks, we don't have
180          to worry about the close-on-exec flag here.  */
181       if (!DuplicateHandle (GetCurrentProcess (), out,
182                             GetCurrentProcess (), &err,
183                             0, TRUE, DUPLICATE_SAME_ACCESS))
184         {
185           /* If that fails, do this as a fall back.  */
186           err = out;
187           system_printf ("couldn't make stderr distinct from stdout, %E");
188         }
189     }
190
191   init_std_file_from_handle (1, out);
192   init_std_file_from_handle (2, err);
193 }
194
195 const int dtable::initial_archetype_size;
196
197 fhandler_base *
198 dtable::find_archetype (device& dev)
199 {
200   for (unsigned i = 0; i < farchetype; i++)
201     if (archetypes[i]->get_device () == (DWORD) dev)
202       return archetypes[i];
203   return NULL;
204 }
205
206 fhandler_base **
207 dtable::add_archetype ()
208 {
209   if (farchetype++ >= narchetypes)
210     archetypes = (fhandler_base **) crealloc_abort (archetypes, (narchetypes += initial_archetype_size) * sizeof archetypes[0]);
211   return archetypes + farchetype - 1;
212 }
213
214 void
215 dtable::delete_archetype (fhandler_base *fh)
216 {
217   for (unsigned i = 0; i < farchetype; i++)
218     if (fh == archetypes[i])
219       {
220         debug_printf ("deleting element %d for %s", i, fh->get_name ());
221         if (i < --farchetype)
222           archetypes[i] = archetypes[farchetype];
223         break;
224       }
225
226   delete fh;
227 }
228
229 int
230 dtable::find_unused_handle (int start)
231 {
232   do
233     {
234       for (size_t i = start; i < size; i++)
235         /* See if open -- no need for overhead of not_open */
236         if (fds[i] == NULL)
237           return i;
238     }
239   while (extend (NOFILE_INCR));
240   return -1;
241 }
242
243 void
244 dtable::release (int fd)
245 {
246   if (!not_open (fd))
247     {
248       if (fds[fd]->need_fixup_before ())
249         dec_need_fixup_before ();
250       delete fds[fd];
251       fds[fd] = NULL;
252     }
253 }
254
255 extern "C" int
256 cygwin_attach_handle_to_fd (char *name, int fd, HANDLE handle, mode_t bin,
257                             DWORD myaccess)
258 {
259   if (fd == -1)
260     fd = cygheap->fdtab.find_unused_handle ();
261   fhandler_base *fh = build_fh_name (name);
262   cygheap->fdtab[fd] = fh;
263   fh->init (handle, myaccess, bin ?: fh->pc_binmode ());
264   return fd;
265 }
266
267 void
268 dtable::init_std_file_from_handle (int fd, HANDLE handle)
269 {
270   CONSOLE_SCREEN_BUFFER_INFO buf;
271   DCB dcb;
272   unsigned bin = O_BINARY;
273   device dev = {};
274
275   first_fd_for_open = 0;
276
277   if (!not_open (fd))
278     return;
279
280   SetLastError (0);
281   DWORD access = 0;
282   DWORD ft = GetFileType (handle);
283   char name[NT_MAX_PATH];
284   name[0] = '\0';
285   if (ft == FILE_TYPE_UNKNOWN && GetLastError () == ERROR_INVALID_HANDLE)
286     /* can't figure out what this is */;
287   else if (ft == FILE_TYPE_PIPE)
288     {
289       int rcv = 0, len = sizeof (int);
290
291       if (handle_to_fn (handle, name))
292         dev.parse (name);
293       else if (strcmp (name, ":sock:") == 0
294                /* NtQueryObject returns an error when called on an LSP socket
295                   handle.  While fdsock now tries to fetch the underlying
296                   base socket, this only works on Vista and later. */
297                || (strcmp (name, unknown_file) == 0
298                    && !::getsockopt ((SOCKET) handle, SOL_SOCKET, SO_RCVBUF,
299                                      (char *) &rcv, &len)))
300         {
301           /* socket */
302           dev = *tcp_dev;
303           name[0] = '\0';
304         }
305       else if (fd == 0)
306         dev = *piper_dev;
307       else
308         dev = *pipew_dev;
309     }
310   else if (GetConsoleScreenBufferInfo (handle, &buf)
311            || GetNumberOfConsoleInputEvents (handle, (DWORD *) &buf))
312     {
313       /* Console I/O */
314       if (myself->ctty > 0)
315         dev.parse (myself->ctty);
316       else
317         dev.parse (FH_CONSOLE);
318     }
319   else if (GetCommState (handle, &dcb))
320     /* FIXME: Not right - assumes ttyS0 */
321     dev.parse (DEV_SERIAL_MAJOR, 0);
322   else
323     /* Try to figure it out from context - probably a disk file */
324     handle_to_fn (handle, name);
325
326   if (!name[0] && !dev)
327     fds[fd] = NULL;
328   else
329     {
330       fhandler_base *fh;
331
332       if (dev)
333         fh = build_fh_dev (dev);
334       else
335         fh = build_fh_name (name);
336
337       if (name[0])
338         {
339           bin = fh->pc_binmode ();
340           if (!bin)
341             {
342               bin = fh->get_default_fmode (O_RDWR);
343               if (!bin && dev)
344                 bin = O_BINARY;
345             }
346         }
347
348       IO_STATUS_BLOCK io;
349       FILE_ACCESS_INFORMATION fai;
350
351       /* Console windows are not kernel objects, so the access mask returned
352          by NtQueryInformationFile is meaningless.  CMD always hands down
353          stdin handles as R/O handles, but our tty slave sides are R/W. */
354       if (dev == FH_TTY || iscons_dev (dev) || dev.get_major () == DEV_TTYS_MAJOR)
355         access |= GENERIC_READ | GENERIC_WRITE;
356       else if (NT_SUCCESS (NtQueryInformationFile (handle, &io, &fai,
357                                                    sizeof fai,
358                                                    FileAccessInformation)))
359         {
360           if (fai.AccessFlags & FILE_READ_DATA)
361             access |= GENERIC_READ;
362           if (fai.AccessFlags & FILE_WRITE_DATA)
363             access |= GENERIC_WRITE;
364         }
365       else if (fd == 0)
366         access |= GENERIC_READ;
367       else
368         access |= GENERIC_WRITE;  /* Should be rdwr for stderr but not sure that's
369                                     possible for some versions of handles */
370       /* FIXME: Workaround Windows 7 issue.  If the parent process of
371          the process tree closes the original handles to the console window,
372          strange problems occur when starting child processes later on if
373          stdio redirection is used.
374
375          CV 2009-08-08:  It looks like this problem has been fixed only
376          half-heartedly in RTM.  Unfortunately the new implementation
377          has still a problem which now also occurs on the 32 bit release
378          of Windows 7.  It's still not quite clear what happens but it's
379          easily reproducible.  Just start X via the start menu entry.
380          This opens an xterm window with a shell.  Exit from the shell,
381          and you get a Windows error box reporting a crash in the
382          Console Window Host application (conhost.exe) due to an access
383          violation.
384
385          This needs further investigation but the workaround not to close
386          the handles will have a marginal hit of three extra handles per
387          process at most. */
388       if (!fh->init (iscons_dev (dev) && wincap.has_console_handle_problem ()
389                      ? INVALID_HANDLE_VALUE : handle, access, bin))
390         api_fatal ("couldn't initialize fd %d for %s", fd, fh->get_name ());
391
392       cygheap->fdtab[fd] = fh;
393       set_std_handle (fd);
394       paranoid_printf ("fd %d, handle %p", fd, handle);
395     }
396 }
397
398 #define cnew(name, ...) \
399   ({ \
400     void* ptr = (void*) ccalloc (HEAP_FHANDLER, 1, sizeof (name)); \
401     ptr ? new (ptr) name (__VA_ARGS__) : NULL; \
402   })
403
404 #define cnew_no_ctor(name, ...) \
405   ({ \
406     void* ptr = (void*) ccalloc (HEAP_FHANDLER, 1, sizeof (name)); \
407     ptr ? new (ptr) name (ptr) : NULL; \
408   })
409
410 fhandler_base *
411 build_fh_name (const char *name, unsigned opt, suffix_info *si)
412 {
413   path_conv pc (name, opt | PC_NULLEMPTY | PC_POSIX, si);
414   if (pc.error)
415     {
416       fhandler_base *fh = cnew (fhandler_nodevice);
417       if (fh)
418         fh->set_error (pc.error);
419       set_errno (fh ? pc.error : EMFILE);
420       return fh;
421     }
422
423   return build_fh_pc (pc);
424 }
425
426 fhandler_base *
427 build_fh_dev (const device& dev, const char *unix_name)
428 {
429   path_conv pc (dev);
430   if (unix_name)
431     pc.set_normalized_path (unix_name);
432   else
433     pc.set_normalized_path (dev.name);
434   return build_fh_pc (pc);
435 }
436
437 #define fh_unset ((fhandler_base *) 1)
438
439 static fhandler_base *
440 fh_alloc (path_conv& pc)
441 {
442   fhandler_base *fh = fh_unset;
443   fhandler_base *fhraw = NULL;
444
445   switch (pc.dev.get_major ())
446     {
447     case DEV_TTYS_MAJOR:
448       fh = cnew (fhandler_pty_slave, pc.dev.get_minor ());
449       break;
450     case DEV_TTYM_MAJOR:
451       fh = cnew (fhandler_pty_master, pc.dev.get_minor ());
452       break;
453     case DEV_CYGDRIVE_MAJOR:
454       fh = cnew (fhandler_cygdrive);
455       break;
456     case DEV_FLOPPY_MAJOR:
457     case DEV_CDROM_MAJOR:
458     case DEV_SD_MAJOR:
459     case DEV_SD1_MAJOR:
460     case DEV_SD2_MAJOR:
461     case DEV_SD3_MAJOR:
462     case DEV_SD4_MAJOR:
463     case DEV_SD5_MAJOR:
464     case DEV_SD6_MAJOR:
465     case DEV_SD7_MAJOR:
466       fh = cnew (fhandler_dev_floppy);
467       break;
468     case DEV_TAPE_MAJOR:
469       fh = cnew (fhandler_dev_tape);
470       break;
471     case DEV_SERIAL_MAJOR:
472       fh = cnew (fhandler_serial);
473       break;
474     case DEV_CONS_MAJOR:
475       fh = cnew (fhandler_console, pc.dev);
476       break;
477     default:
478       switch ((int) pc.dev)
479         {
480         case FH_CONSOLE:
481         case FH_CONIN:
482         case FH_CONOUT:
483           fh = cnew (fhandler_console, pc.dev);
484           break;
485         case FH_PTMX:
486           if (pc.isopen ())
487             fh = cnew (fhandler_pty_master, -1);
488           else
489             fhraw = cnew_no_ctor (fhandler_pty_master, -1); 
490           break;
491         case FH_WINDOWS:
492           fh = cnew (fhandler_windows);
493           break;
494         case FH_FIFO:
495           fh = cnew (fhandler_fifo);
496           break;
497         case FH_PIPE:
498         case FH_PIPER:
499         case FH_PIPEW:
500           fh = cnew (fhandler_pipe);
501           break;
502         case FH_TCP:
503         case FH_UDP:
504         case FH_ICMP:
505         case FH_UNIX:
506         case FH_STREAM:
507         case FH_DGRAM:
508           fh = cnew (fhandler_socket);
509           break;
510         case FH_FS:
511           fh = cnew (fhandler_disk_file);
512           break;
513         case FH_NULL:
514           fh = cnew (fhandler_dev_null);
515           break;
516         case FH_ZERO:
517         case FH_FULL:
518           fh = cnew (fhandler_dev_zero);
519           break;
520         case FH_RANDOM:
521         case FH_URANDOM:
522           fh = cnew (fhandler_dev_random);
523           break;
524         case FH_MEM:
525         case FH_PORT:
526           fh = cnew (fhandler_dev_mem);
527           break;
528         case FH_CLIPBOARD:
529           fh = cnew (fhandler_dev_clipboard);
530           break;
531         case FH_OSS_DSP:
532           fh = cnew (fhandler_dev_dsp);
533           break;
534         case FH_PROC:
535           fh = cnew (fhandler_proc);
536           break;
537         case FH_REGISTRY:
538           fh = cnew (fhandler_registry);
539           break;
540         case FH_PROCESS:
541         case FH_PROCESSFD:
542           fh = cnew (fhandler_process);
543           break;
544         case FH_PROCNET:
545           fh = cnew (fhandler_procnet);
546           break;
547         case FH_PROCSYS:
548           fh = cnew (fhandler_procsys);
549           break;
550         case FH_PROCSYSVIPC:
551           fh = cnew (fhandler_procsysvipc);
552           break;
553         case FH_NETDRIVE:
554           fh = cnew (fhandler_netdrive);
555           break;
556         case FH_TTY:
557           if (!pc.isopen ())
558             fhraw = cnew_no_ctor (fhandler_console, -1); 
559           else if (myself->ctty <= 0
560                    && !myself->set_ctty (fhandler_termios::last, 0))
561             /* no tty assigned */;
562           else if (iscons_dev (myself->ctty))
563             fh = cnew (fhandler_console, pc.dev);
564           else
565             fh = cnew (fhandler_pty_slave, myself->ctty);
566           break;
567         case FH_KMSG:
568           fh = cnew (fhandler_mailslot);
569           break;
570       }
571     }
572
573   /* If `fhraw' is set that means that this fhandler is just a dummy
574      set up for stat().  Mock it up for use by stat without actually
575      trying to do any real initialization.  */
576   if (fhraw)
577     {
578       fh = fhraw;
579       fh->set_name (pc);
580       if (fh->use_archetype ())
581         fh->archetype = fh;
582     }
583   if (fh == fh_unset)
584     fh = cnew (fhandler_nodevice);
585   else if (fh->dev () == FH_ERROR)
586     {
587       delete fh;
588       fh = NULL;
589     }
590   return fh;
591 }
592
593 fhandler_base *
594 build_fh_pc (path_conv& pc, bool set_name)
595 {
596   fhandler_base *fh = fh_alloc (pc);
597
598   if (!fh)
599     {
600       set_errno (ENXIO);
601       goto out;
602     }
603   else if (fh->dev () != FH_NADA)
604     fh->set_name (fh->dev ().name);
605   else if (set_name)
606     fh->set_name (pc);
607
608   if (!fh->use_archetype ())
609     /* doesn't use archetypes */;
610   else if ((fh->archetype = cygheap->fdtab.find_archetype (fh->dev ())))
611     debug_printf ("found an archetype for %s(%d/%d) io_handle %p", fh->get_name (), fh->dev ().get_major (), fh->dev ().get_minor (),
612                   fh->archetype->get_io_handle ());
613   else
614     {
615       fh->archetype = fh->clone ();
616       debug_printf ("created an archetype (%p) for %s(%d/%d)", fh->archetype, fh->get_name (), fh->dev ().get_major (), fh->dev ().get_minor ());
617       fh->archetype->archetype = NULL;
618       *cygheap->fdtab.add_archetype () = fh->archetype;
619     }
620
621   /* The fhandler_termios constructor keeps track of the last tty-like thing
622      opened but we're only interested in this if we don't have a controlling
623      terminal since we could potentially want to open it if /dev/tty is
624      referenced. */
625   if (myself->ctty > 0 || !fh->is_tty () || !pc.isctty_capable ())
626     fhandler_termios::last = NULL;
627
628 out:
629   debug_printf ("fh %p, dev %p", fh, (DWORD) fh->dev ());
630   return fh;
631 }
632
633 fhandler_base *
634 dtable::dup_worker (fhandler_base *oldfh, int flags)
635 {
636   /* Don't call set_name in build_fh_pc.  It will be called in
637      fhandler_base::operator= below.  Calling it twice will result
638      in double allocation. */
639   fhandler_base *newfh = oldfh->clone ();
640   if (!newfh)
641     debug_printf ("build_fh_pc failed");
642   else
643     {
644       if (!oldfh->archetype)
645         newfh->set_io_handle (NULL);
646
647       newfh->pc.reset_conv_handle ();
648       if (oldfh->dup (newfh, flags))
649         {
650           delete newfh;
651           newfh = NULL;
652           debug_printf ("oldfh->dup failed");
653         }
654       else
655         {
656           newfh->usecount = 0;
657           newfh->archetype_usecount (1);
658           /* The O_CLOEXEC flag enforces close-on-exec behaviour. */
659           newfh->set_close_on_exec (!!(flags & O_CLOEXEC));
660           debug_printf ("duped '%s' old %p, new %p", oldfh->get_name (), oldfh->get_io_handle (), newfh->get_io_handle ());
661 #ifdef DEBUGGING
662           debug_printf ("duped output_handles old %p, new %p",
663                         oldfh->get_output_handle (),
664                         newfh->get_output_handle ());
665           debug_printf ("duped output_handles archetype old %p, archetype new %p",
666                         oldfh->archetype->get_output_handle (),
667                         newfh->archetype->get_output_handle ());
668 #endif /*DEBUGGING*/
669         }
670     }
671   return newfh;
672 }
673
674 int
675 dtable::dup3 (int oldfd, int newfd, int flags)
676 {
677   int res = -1;
678   fhandler_base *newfh = NULL;  // = NULL to avoid an incorrect warning
679
680   MALLOC_CHECK;
681   debug_printf ("dup3 (%d, %d, %p)", oldfd, newfd, flags);
682   lock ();
683
684   if (not_open (oldfd))
685     {
686       syscall_printf ("fd %d not open", oldfd);
687       set_errno (EBADF);
688       goto done;
689     }
690   if (newfd < 0)
691     {
692       syscall_printf ("new fd out of bounds: %d", newfd);
693       set_errno (EBADF);
694       goto done;
695     }
696   if ((flags & ~O_CLOEXEC) != 0)
697     {
698       syscall_printf ("invalid flags value %x", flags);
699       set_errno (EINVAL);
700       return -1;
701     }
702
703   /* This is a temporary kludge until all utilities can catch up with
704      a change in behavior that implements linux functionality:  opening
705      a tty should not automatically cause it to become the controlling
706      tty for the process.  */
707   if (newfd > 2)
708     flags |= O_NOCTTY;
709
710   if ((newfh = dup_worker (fds[oldfd], flags)) == NULL)
711     {
712       res = -1;
713       goto done;
714     }
715
716   debug_printf ("newfh->io_handle %p, oldfh->io_handle %p, new win32_name %p, old win32_name %p",
717                 newfh->get_io_handle (), fds[oldfd]->get_io_handle (), newfh->get_win32_name (), fds[oldfd]->get_win32_name ());
718
719   if (!not_open (newfd))
720     close (newfd);
721   else if ((size_t) newfd < size)
722     /* nothing to do */;
723   else if (find_unused_handle (newfd) < 0)
724     {
725       newfh->close ();
726       res = -1;
727       goto done;
728     }
729
730   fds[newfd] = newfh;
731
732   if ((res = newfd) <= 2)
733     set_std_handle (res);
734
735 done:
736   MALLOC_CHECK;
737   unlock ();
738   syscall_printf ("%d = dup3 (%d, %d, %p)", res, oldfd, newfd, flags);
739
740   return res;
741 }
742
743 bool
744 dtable::select_read (int fd, select_stuff *ss)
745 {
746   if (not_open (fd))
747     {
748       set_errno (EBADF);
749       return false;
750     }
751   fhandler_base *fh = fds[fd];
752   select_record *s = fh->select_read (ss);
753   s->fd = fd;
754   if (!s->fh)
755     s->fh = fh;
756   s->thread_errno = 0;
757   debug_printf ("%s fd %d", fh->get_name (), fd);
758   return true;
759 }
760
761 bool
762 dtable::select_write (int fd, select_stuff *ss)
763 {
764   if (not_open (fd))
765     {
766       set_errno (EBADF);
767       return NULL;
768     }
769   fhandler_base *fh = fds[fd];
770   select_record *s = fh->select_write (ss);
771   s->fd = fd;
772   s->fh = fh;
773   s->thread_errno = 0;
774   debug_printf ("%s fd %d", fh->get_name (), fd);
775   return true;
776 }
777
778 bool
779 dtable::select_except (int fd, select_stuff *ss)
780 {
781   if (not_open (fd))
782     {
783       set_errno (EBADF);
784       return NULL;
785     }
786   fhandler_base *fh = fds[fd];
787   select_record *s = fh->select_except (ss);
788   s->fd = fd;
789   s->fh = fh;
790   s->thread_errno = 0;
791   debug_printf ("%s fd %d", fh->get_name (), fd);
792   return true;
793 }
794
795 void
796 dtable::move_fd (int from, int to)
797 {
798   // close (to); /* It is assumed that this is close-on-exec */
799   fds[to] = fds[from];
800   fds[from] = NULL;
801 }
802
803 void
804 dtable::set_file_pointers_for_exec ()
805 {
806 /* This is not POSIX-compliant so the function is only called for
807    non-Cygwin processes. */
808   LONG off_high = 0;
809   lock ();
810   fhandler_base *fh;
811   for (size_t i = 0; i < size; i++)
812     if ((fh = fds[i]) != NULL && fh->get_flags () & O_APPEND)
813       SetFilePointer (fh->get_handle (), 0, &off_high, FILE_END);
814   unlock ();
815 }
816
817 void
818 dtable::fixup_after_exec ()
819 {
820   first_fd_for_open = 0;
821   fhandler_base *fh;
822   for (size_t i = 0; i < size; i++)
823     if ((fh = fds[i]) != NULL)
824       {
825         fh->clear_readahead ();
826         fh->fixup_after_exec ();
827         if (fh->close_on_exec ())
828           {
829             if (fh->archetype)
830               {
831                 debug_printf ("closing fd %d since it is an archetype", i);
832                 fh->close_with_arch ();
833               }
834             release (i);
835           }
836         else if (fh->get_popen_pid ())
837           close (i);
838         else if (i == 0)
839           SetStdHandle (std_consts[i], fh->get_io_handle ());
840         else if (i <= 2)
841           SetStdHandle (std_consts[i], fh->get_output_handle ());
842       }
843 }
844
845 void
846 dtable::fixup_after_fork (HANDLE parent)
847 {
848   fhandler_base *fh;
849   for (size_t i = 0; i < size; i++)
850     if ((fh = fds[i]) != NULL)
851       {
852         if (fh->close_on_exec () || fh->need_fork_fixup ())
853           {
854             debug_printf ("fd %d (%s)", i, fh->get_name ());
855             fh->fixup_after_fork (parent);
856           }
857         if (i == 0)
858           SetStdHandle (std_consts[i], fh->get_io_handle ());
859         else if (i <= 2)
860           SetStdHandle (std_consts[i], fh->get_output_handle ());
861       }
862 }
863
864 static void
865 decode_tty (char *buf, WCHAR *w32)
866 {
867   int ttyn = wcstol (w32, NULL, 10);
868   __small_sprintf (buf, "/dev/pty%d", ttyn);
869 }
870
871 /* Try to derive posix filename from given handle.  Return true if
872    the handle is associated with a cygwin tty. */
873 static bool
874 handle_to_fn (HANDLE h, char *posix_fn)
875 {
876   tmp_pathbuf tp;
877   ULONG len = 0;
878   WCHAR *maxmatchdos = NULL;
879   int maxmatchlen = 0;
880   OBJECT_NAME_INFORMATION *ntfn = (OBJECT_NAME_INFORMATION *) tp.w_get ();
881
882   NTSTATUS status = NtQueryObject (h, ObjectNameInformation, ntfn, 65536, &len);
883   if (!NT_SUCCESS (status))
884     debug_printf ("NtQueryObject failed, %p", status);
885   // NT seems to do this on an unopened file
886   else if (!ntfn->Name.Buffer)
887     debug_printf ("nt->Name.Buffer == NULL");
888   else
889     {
890       WCHAR *w32 = ntfn->Name.Buffer;
891       size_t w32len = ntfn->Name.Length / sizeof (WCHAR);
892       w32[w32len] = L'\0';
893
894       if (wcscasecmp (w32, DEV_NULL) == 0)
895         {
896           strcpy (posix_fn, "/dev/null");
897           return false;
898         }
899
900       if (wcscasecmp (w32, DEV_SOCKET) == 0)
901         {
902           strcpy (posix_fn, ":sock:");
903           return false;
904         }
905
906       if (wcsncasecmp (w32, DEV_NAMED_PIPE, DEV_NAMED_PIPE_LEN) == 0)
907         {
908           w32 += DEV_NAMED_PIPE_LEN;
909           if (wcsncmp (w32, L"cygwin-", WCLEN (L"cygwin-")) != 0)
910             return false;
911           w32 += WCLEN (L"cygwin-");
912           /* Check for installation key and trailing dash. */
913           w32len = installation_key.Length / sizeof (WCHAR);
914           if (w32len && wcsncmp (w32, installation_key.Buffer, w32len) != 0)
915             return false;
916           w32 += w32len;
917           if (*w32 != L'-')
918             return false;
919           ++w32;
920           bool istty = wcsncmp (w32, L"pty", WCLEN (L"pty")) == 0;
921           if (istty)
922             decode_tty (posix_fn, w32 + WCLEN (L"pty"));
923           else if (wcsncmp (w32, L"pipe", WCLEN (L"pipe")) == 0)
924             strcpy (posix_fn, "/dev/pipe");
925           return istty;
926         }
927
928       WCHAR fnbuf[64 * 1024];
929       if (wcsncasecmp (w32, DEVICE_PREFIX, DEVICE_PREFIX_LEN) != 0
930           || !QueryDosDeviceW (NULL, fnbuf, sizeof (fnbuf)))
931         {
932           sys_wcstombs (posix_fn, NT_MAX_PATH, w32, w32len);
933           return false;
934         }
935
936       for (WCHAR *s = fnbuf; *s; s = wcschr (s, '\0') + 1)
937         {
938           WCHAR device[NT_MAX_PATH];
939           if (!QueryDosDeviceW (s, device, sizeof (device)))
940             continue;
941           if (wcschr (s, ':') == NULL)
942             continue;
943           WCHAR *q = wcsrchr (device, ';');
944           if (q)
945             {
946               WCHAR *r = wcschr (q, '\\');
947               if (r)
948                 wcscpy (q, r + 1);
949             }
950           int devlen = wcslen (device);
951           if (device[devlen - 1] == L'\\')
952             device[--devlen] = L'\0';
953           if (devlen < maxmatchlen)
954             continue;
955           if (wcsncmp (device, w32, devlen) != 0||
956               (w32[devlen] != L'\0' && w32[devlen] != L'\\'))
957             continue;
958           maxmatchlen = devlen;
959           maxmatchdos = s;
960           debug_printf ("current match '%W' = '%W'\n", s, device);
961         }
962
963       if (maxmatchlen)
964         {
965           WCHAR *p = wcschr (w32 + DEVICE_PREFIX_LEN, L'\\');
966           size_t n = wcslen (maxmatchdos);
967           WCHAR ch;
968           if (!p)
969             ch = L'\0';
970           else
971             {
972               if (maxmatchdos[n - 1] == L'\\')
973                 n--;
974               w32 += maxmatchlen - n;
975               ch = L'\\';
976             }
977           memcpy (w32, maxmatchdos, n * sizeof (WCHAR));
978           w32[n] = ch;
979         }
980       else if (wcsncmp (w32, DEV_REMOTE, DEV_REMOTE_LEN) == 0)
981         {
982           w32 += DEV_REMOTE_LEN - 2;
983           *w32 = L'\\';
984           debug_printf ("remote drive");
985         }
986       else if (wcsncmp (w32, DEV_REMOTE1, DEV_REMOTE1_LEN) == 0)
987         {
988           w32 += DEV_REMOTE1_LEN - 2;
989           *w32 = L'\\';
990           debug_printf ("remote drive");
991         }
992
993       cygwin_conv_path (CCP_WIN_W_TO_POSIX | CCP_ABSOLUTE, w32, posix_fn,
994                         NT_MAX_PATH);
995
996       debug_printf ("derived path '%W', posix '%s'", w32, posix_fn);
997       return false;
998     }
999
1000   strcpy (posix_fn,  unknown_file);
1001   return false;
1002 }
1003
1004 void
1005 dtable::fixup_before_fork (DWORD target_proc_id)
1006 {
1007   lock ();
1008   fhandler_base *fh;
1009   for (size_t i = 0; i < size; i++)
1010     if ((fh = fds[i]) != NULL)
1011       {
1012         debug_printf ("fd %d (%s)", i, fh->get_name ());
1013         fh->fixup_before_fork_exec (target_proc_id);
1014       }
1015   unlock ();
1016 }
1017
1018 void
1019 dtable::fixup_before_exec (DWORD target_proc_id)
1020 {
1021   lock ();
1022   fhandler_base *fh;
1023   for (size_t i = 0; i < size; i++)
1024     if ((fh = fds[i]) != NULL && !fh->close_on_exec ())
1025       {
1026         debug_printf ("fd %d (%s)", i, fh->get_name ());
1027         fh->fixup_before_fork_exec (target_proc_id);
1028       }
1029   unlock ();
1030 }