OSDN Git Service

04499e6e7502357977090cd488f0539a24c148ef
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / fhandler.cc
1 /* fhandler.cc.  See console.cc for fhandler_console functions.
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 #include "winsup.h"
13 #include <unistd.h>
14 #include <stdlib.h>
15 #include <sys/uio.h>
16 #include <sys/acl.h>
17 #include "cygerrno.h"
18 #include "perprocess.h"
19 #include "security.h"
20 #include "cygwin/version.h"
21 #include "path.h"
22 #include "fhandler.h"
23 #include "dtable.h"
24 #include "cygheap.h"
25 #include "pinfo.h"
26 #include <assert.h>
27 #include <winioctl.h>
28 #include "ntdll.h"
29 #include "cygtls.h"
30 #include "sigproc.h"
31 #include "shared_info.h"
32 #include <asm/socket.h>
33
34 #define MAX_OVERLAPPED_WRITE_LEN (64 * 1024 * 1024)
35 #define MIN_OVERLAPPED_WRITE_LEN (1 * 1024 * 1024)
36
37 static const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
38
39 struct __cygwin_perfile *perfile_table;
40
41 HANDLE NO_COPY fhandler_base_overlapped::asio_done;
42 LONG NO_COPY fhandler_base_overlapped::asio_close_counter;
43
44 void
45 fhandler_base::reset (const fhandler_base *from)
46 {
47   pc << from->pc;
48   rabuf = NULL;
49   ralen = 0;
50   raixget = 0;
51   raixput = 0;
52   rabuflen = 0;
53 }
54
55 int
56 fhandler_base::puts_readahead (const char *s, size_t len)
57 {
58   int success = 1;
59   while ((len == (size_t) -1 ? *s : len--)
60          && (success = put_readahead (*s++) > 0))
61     continue;
62   return success;
63 }
64
65 int
66 fhandler_base::put_readahead (char value)
67 {
68   char *newrabuf;
69   if (raixput < rabuflen)
70     /* Nothing to do */;
71   else if ((newrabuf = (char *) realloc (rabuf, rabuflen += 32)))
72     rabuf = newrabuf;
73   else
74     return 0;
75
76   rabuf[raixput++] = value;
77   ralen++;
78   return 1;
79 }
80
81 int
82 fhandler_base::get_readahead ()
83 {
84   int chret = -1;
85   if (raixget < ralen)
86     chret = ((unsigned char) rabuf[raixget++]) & 0xff;
87   /* FIXME - not thread safe */
88   if (raixget >= ralen)
89     raixget = raixput = ralen = 0;
90   return chret;
91 }
92
93 int
94 fhandler_base::peek_readahead (int queryput)
95 {
96   int chret = -1;
97   if (!queryput && raixget < ralen)
98     chret = ((unsigned char) rabuf[raixget]) & 0xff;
99   else if (queryput && raixput > 0)
100     chret = ((unsigned char) rabuf[raixput - 1]) & 0xff;
101   return chret;
102 }
103
104 void
105 fhandler_base::set_readahead_valid (int val, int ch)
106 {
107   if (!val)
108     ralen = raixget = raixput = 0;
109   if (ch != -1)
110     put_readahead (ch);
111 }
112
113 int
114 fhandler_base::eat_readahead (int n)
115 {
116   int oralen = ralen;
117   if (n < 0)
118     n = ralen;
119   if (n > 0 && ralen)
120     {
121       if ((int) (ralen -= n) < 0)
122         ralen = 0;
123
124       if (raixget >= ralen)
125         raixget = raixput = ralen = 0;
126       else if (raixput > ralen)
127         raixput = ralen;
128     }
129
130   return oralen;
131 }
132
133 int
134 fhandler_base::get_readahead_into_buffer (char *buf, size_t buflen)
135 {
136   int ch;
137   int copied_chars = 0;
138
139   while (buflen)
140     if ((ch = get_readahead ()) < 0)
141       break;
142     else
143       {
144         buf[copied_chars++] = (unsigned char)(ch & 0xff);
145         buflen--;
146       }
147
148   return copied_chars;
149 }
150
151 /* Record the file name. and name hash */
152 void
153 fhandler_base::set_name (path_conv &in_pc)
154 {
155   pc << in_pc;
156 }
157
158 char *fhandler_base::get_proc_fd_name (char *buf)
159 {
160   if (get_name ())
161     return strcpy (buf, get_name ());
162   if (dev ().name)
163     return strcpy (buf, dev ().name);
164   return strcpy (buf, "");
165 }
166
167 /* Detect if we are sitting at EOF for conditions where Windows
168    returns an error but UNIX doesn't.  */
169 int __stdcall
170 is_at_eof (HANDLE h)
171 {
172   IO_STATUS_BLOCK io;
173   FILE_POSITION_INFORMATION fpi;
174   FILE_STANDARD_INFORMATION fsi;
175
176   if (NT_SUCCESS (NtQueryInformationFile (h, &io, &fsi, sizeof fsi,
177                                           FileStandardInformation))
178       && NT_SUCCESS (NtQueryInformationFile (h, &io, &fpi, sizeof fpi,
179                                              FilePositionInformation))
180       && fsi.EndOfFile.QuadPart == fpi.CurrentByteOffset.QuadPart)
181     return 1;
182   return 0;
183 }
184
185 void
186 fhandler_base::set_flags (int flags, int supplied_bin)
187 {
188   int bin;
189   int fmode;
190   debug_printf ("flags %p, supplied_bin %p", flags, supplied_bin);
191   if ((bin = flags & (O_BINARY | O_TEXT)))
192     debug_printf ("O_TEXT/O_BINARY set in flags %p", bin);
193   else if (rbinset () && wbinset ())
194     bin = rbinary () ? O_BINARY : O_TEXT;       // FIXME: Not quite right
195   else if ((fmode = get_default_fmode (flags)) & O_BINARY)
196     bin = O_BINARY;
197   else if (fmode & O_TEXT)
198     bin = O_TEXT;
199   else if (supplied_bin)
200     bin = supplied_bin;
201   else
202     bin = wbinary () || rbinary () ? O_BINARY : O_TEXT;
203
204   openflags = flags | bin;
205
206   bin &= O_BINARY;
207   rbinary (bin ? true : false);
208   wbinary (bin ? true : false);
209   syscall_printf ("filemode set to %s", bin ? "binary" : "text");
210 }
211
212 /* Normal file i/o handlers.  */
213
214 /* Cover function to ReadFile to achieve (as much as possible) Posix style
215    semantics and use of errno.  */
216 void __stdcall
217 fhandler_base::raw_read (void *ptr, size_t& ulen)
218 {
219 #define bytes_read ulen
220
221   int try_noreserve = 1;
222   DWORD len = ulen;
223
224 retry:
225   ulen = (size_t) -1;
226   BOOL res = ReadFile (get_handle (), ptr, len, (DWORD *) &ulen, NULL);
227   if (!res)
228     {
229       /* Some errors are not really errors.  Detect such cases here.  */
230
231       DWORD  errcode = GetLastError ();
232       switch (errcode)
233         {
234         case ERROR_BROKEN_PIPE:
235           /* This is really EOF.  */
236           bytes_read = 0;
237           break;
238         case ERROR_MORE_DATA:
239           /* `bytes_read' is supposedly valid.  */
240           break;
241         case ERROR_NOACCESS:
242           if (is_at_eof (get_handle ()))
243             {
244               bytes_read = 0;
245               break;
246             }
247           if (try_noreserve)
248             {
249               try_noreserve = 0;
250               switch (mmap_is_attached_or_noreserve (ptr, len))
251                 {
252                 case MMAP_NORESERVE_COMMITED:
253                   goto retry;
254                 case MMAP_RAISE_SIGBUS:
255                   raise(SIGBUS);
256                 case MMAP_NONE:
257                   break;
258                 }
259             }
260           /*FALLTHRU*/
261         case ERROR_INVALID_FUNCTION:
262         case ERROR_INVALID_PARAMETER:
263         case ERROR_INVALID_HANDLE:
264           if (pc.isdir ())
265             {
266               set_errno (EISDIR);
267               bytes_read = (size_t) -1;
268               break;
269             }
270         default:
271           syscall_printf ("ReadFile %s(%p) failed, %E", get_name (), get_handle ());
272           __seterrno_from_win_error (errcode);
273           bytes_read = (size_t) -1;
274           break;
275         }
276     }
277 #undef bytes_read
278 }
279
280 /* Cover function to WriteFile to provide Posix interface and semantics
281    (as much as possible).  */
282 ssize_t __stdcall
283 fhandler_base::raw_write (const void *ptr, size_t len)
284 {
285   NTSTATUS status;
286   IO_STATUS_BLOCK io;
287   static _RDATA LARGE_INTEGER off_current =
288                           { QuadPart:FILE_USE_FILE_POINTER_POSITION };
289   static _RDATA LARGE_INTEGER off_append =
290                           { QuadPart:FILE_WRITE_TO_END_OF_FILE };
291
292   status = NtWriteFile (get_output_handle (), NULL, NULL, NULL, &io,
293                         (PVOID) ptr, len,
294                         (get_flags () & O_APPEND) ? &off_append : &off_current,
295                         NULL);
296   if (!NT_SUCCESS (status))
297     {
298       __seterrno_from_nt_status (status);
299       if (get_errno () == EPIPE)
300         raise (SIGPIPE);
301       return -1;
302     }
303   return io.Information;
304 }
305
306 int
307 fhandler_base::get_default_fmode (int flags)
308 {
309   int fmode = __fmode;
310   if (perfile_table)
311     {
312       size_t nlen = strlen (get_name ());
313       unsigned accflags = (flags & O_ACCMODE);
314       for (__cygwin_perfile *pf = perfile_table; pf->name; pf++)
315         if (!*pf->name && (pf->flags & O_ACCMODE) == accflags)
316           {
317             fmode = pf->flags & ~O_ACCMODE;
318             break;
319           }
320         else
321           {
322             size_t pflen = strlen (pf->name);
323             const char *stem = get_name () + nlen - pflen;
324             if (pflen > nlen || (stem != get_name () && !isdirsep (stem[-1])))
325               continue;
326             else if ((pf->flags & O_ACCMODE) == accflags
327                      && pathmatch (stem, pf->name, !!pc.objcaseinsensitive ()))
328               {
329                 fmode = pf->flags & ~O_ACCMODE;
330                 break;
331               }
332           }
333     }
334   return fmode;
335 }
336
337 bool
338 fhandler_base::device_access_denied (int flags)
339 {
340   int mode = 0;
341
342   if (flags & O_RDWR)
343     mode |= R_OK | W_OK;
344   if (flags & (O_WRONLY | O_APPEND))
345     mode |= W_OK;
346   if (!mode)
347     mode |= R_OK;
348
349   return fhaccess (mode, true);
350 }
351
352 int
353 fhandler_base::fhaccess (int flags, bool effective)
354 {
355   int res = -1;
356   if (error ())
357     {
358       set_errno (error ());
359       goto done;
360     }
361
362   if (!exists ())
363     {
364       set_errno (ENOENT);
365       goto done;
366     }
367
368   if (!(flags & (R_OK | W_OK | X_OK)))
369     return 0;
370
371   if (is_fs_special ())
372     /* short circuit */;
373   else if (has_attribute (FILE_ATTRIBUTE_READONLY) && (flags & W_OK)
374            && !pc.isdir ())
375     goto eaccess_done;
376   else if (has_acls ())
377     {
378       res = check_file_access (pc, flags, effective);
379       goto done;
380     }
381   else if (get_device () == FH_REGISTRY && open (O_RDONLY, 0) && get_handle ())
382     {
383       res = check_registry_access (get_handle (), flags, effective);
384       close ();
385       return res;
386     }
387
388   struct __stat64 st;
389   if (fstat (&st))
390     goto done;
391
392   if (flags & R_OK)
393     {
394       if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid))
395         {
396           if (!(st.st_mode & S_IRUSR))
397             goto eaccess_done;
398         }
399       else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid))
400         {
401           if (!(st.st_mode & S_IRGRP))
402             goto eaccess_done;
403         }
404       else if (!(st.st_mode & S_IROTH))
405         goto eaccess_done;
406     }
407
408   if (flags & W_OK)
409     {
410       if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid))
411         {
412           if (!(st.st_mode & S_IWUSR))
413             goto eaccess_done;
414         }
415       else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid))
416         {
417           if (!(st.st_mode & S_IWGRP))
418             goto eaccess_done;
419         }
420       else if (!(st.st_mode & S_IWOTH))
421         goto eaccess_done;
422     }
423
424   if (flags & X_OK)
425     {
426       if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid))
427         {
428           if (!(st.st_mode & S_IXUSR))
429             goto eaccess_done;
430         }
431       else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid))
432         {
433           if (!(st.st_mode & S_IXGRP))
434             goto eaccess_done;
435         }
436       else if (!(st.st_mode & S_IXOTH))
437         goto eaccess_done;
438     }
439
440   res = 0;
441   goto done;
442
443 eaccess_done:
444   set_errno (EACCES);
445 done:
446   if (!res && (flags & W_OK) && get_device () == FH_FS
447       && (pc.fs_flags () & FILE_READ_ONLY_VOLUME))
448     {
449       set_errno (EROFS);
450       res = -1;
451     }
452   debug_printf ("returning %d", res);
453   return res;
454 }
455
456 int
457 fhandler_base::open_with_arch (int flags, mode_t mode)
458 {
459   int res;
460   if (!(res = (archetype && archetype->io_handle)
461         || open (flags, (mode & 07777) & ~cygheap->umask)))
462     {
463       if (archetype)
464         delete archetype;
465     }
466   else if (archetype)
467     {
468       if (!archetype->get_io_handle ())
469         {
470           copyto (archetype);
471           archetype_usecount (1);
472           archetype->archetype = NULL;
473           usecount = 0;
474         }
475       else
476         {
477           char *name;
478           /* Preserve any name (like /dev/tty) derived from build_fh_pc. */
479           if (!get_name ())
480             name = NULL;
481           else
482             {
483               name = (char *) alloca (strlen (get_name ()) + 1);
484               strcpy (name, get_name ());
485             }
486           fhandler_base *arch = archetype;
487           archetype->copyto (this);
488           if (name)
489             set_name (name);
490           archetype = arch;
491           archetype_usecount (1);
492           usecount = 0;
493         }
494       open_setup (flags);
495     }
496
497   close_on_exec (flags & O_CLOEXEC);
498   return res;
499 }
500
501 /* Open system call handler function. */
502 int
503 fhandler_base::open (int flags, mode_t mode)
504 {
505   int res = 0;
506   HANDLE fh;
507   ULONG file_attributes = 0;
508   ULONG shared = (get_major () == DEV_TAPE_MAJOR ? 0 : FILE_SHARE_VALID_FLAGS);
509   ULONG create_disposition;
510   OBJECT_ATTRIBUTES attr;
511   IO_STATUS_BLOCK io;
512   NTSTATUS status;
513   PFILE_FULL_EA_INFORMATION p = NULL;
514   ULONG plen = 0;
515
516   syscall_printf ("(%S, %p)", pc.get_nt_native_path (), flags);
517
518   pc.get_object_attr (attr, *sec_none_cloexec (flags));
519
520   options = FILE_OPEN_FOR_BACKUP_INTENT;
521   switch (query_open ())
522     {
523       case query_read_control:
524         access = READ_CONTROL;
525         break;
526       case query_read_attributes:
527         access = READ_CONTROL | FILE_READ_ATTRIBUTES;
528         break;
529       case query_write_control:
530         access = READ_CONTROL | WRITE_OWNER | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
531         break;
532       case query_write_dac:
533         access = READ_CONTROL | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
534         break;
535       case query_write_attributes:
536         access = READ_CONTROL | FILE_WRITE_ATTRIBUTES;
537         break;
538       default:
539         if ((flags & O_ACCMODE) == O_RDONLY)
540           access = GENERIC_READ;
541         else if ((flags & O_ACCMODE) == O_WRONLY)
542           access = GENERIC_WRITE | READ_CONTROL | FILE_READ_ATTRIBUTES;
543         else
544           access = GENERIC_READ | GENERIC_WRITE;
545         if (flags & O_SYNC)
546           options |= FILE_WRITE_THROUGH;
547         if (flags & O_DIRECT)
548           options |= FILE_NO_INTERMEDIATE_BUFFERING;
549         if (get_major () != DEV_SERIAL_MAJOR && get_major () != DEV_TAPE_MAJOR)
550           {
551             options |= FILE_SYNCHRONOUS_IO_NONALERT;
552             access |= SYNCHRONIZE;
553           }
554         break;
555     }
556
557   /* Don't use the FILE_OVERWRITE{_IF} flags here.  See below for an
558      explanation, why that's not such a good idea. */
559   if ((flags & O_EXCL) && (flags & O_CREAT))
560     create_disposition = FILE_CREATE;
561   else
562     create_disposition = (flags & O_CREAT) ? FILE_OPEN_IF : FILE_OPEN;
563
564   if (get_device () == FH_FS)
565     {
566       /* Add the reparse point flag to native symlinks, otherwise we open the
567          target, not the symlink.  This would break lstat. */
568       if (pc.is_rep_symlink ())
569         options |= FILE_OPEN_REPARSE_POINT;
570
571       if (pc.fs_is_nfs ())
572         {
573           /* Make sure we can read EAs of files on an NFS share.  Also make
574              sure that we're going to act on the file itself, even if it's a
575              a symlink. */
576           access |= FILE_READ_EA;
577           if (query_open ())
578             {
579               if (query_open () >= query_write_control)
580                 access |=  FILE_WRITE_EA;
581               plen = sizeof nfs_aol_ffei;
582               p = (PFILE_FULL_EA_INFORMATION) &nfs_aol_ffei;
583             }
584         }
585
586       /* Starting with Windows 2000, when trying to overwrite an already
587          existing file with FILE_ATTRIBUTE_HIDDEN and/or FILE_ATTRIBUTE_SYSTEM
588          attribute set, CreateFile fails with ERROR_ACCESS_DENIED.
589          Per MSDN you have to create the file with the same attributes as
590          already specified for the file. */
591       if (((flags & O_CREAT) || create_disposition == FILE_OVERWRITE)
592           && has_attribute (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
593         file_attributes |= pc.file_attributes ();
594
595       if (flags & O_CREAT)
596         {
597           file_attributes |= FILE_ATTRIBUTE_NORMAL;
598
599           if (pc.fs_is_nfs ())
600             {
601               /* When creating a file on an NFS share, we have to set the
602                  file mode by writing a NFS fattr3 structure with the
603                  correct mode bits set. */
604               access |= FILE_WRITE_EA;
605               plen = sizeof (FILE_FULL_EA_INFORMATION) + sizeof (NFS_V3_ATTR)
606                      + sizeof (fattr3);
607               p = (PFILE_FULL_EA_INFORMATION) alloca (plen);
608               p->NextEntryOffset = 0;
609               p->Flags = 0;
610               p->EaNameLength = sizeof (NFS_V3_ATTR) - 1;
611               p->EaValueLength = sizeof (fattr3);
612               strcpy (p->EaName, NFS_V3_ATTR);
613               fattr3 *nfs_attr = (fattr3 *) (p->EaName
614                                              + p->EaNameLength + 1);
615               memset (nfs_attr, 0, sizeof (fattr3));
616               nfs_attr->type = NF3REG;
617               nfs_attr->mode = mode;
618             }
619           else if (!has_acls () && !(mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
620             /* If mode has no write bits set, and ACLs are not used, we set
621                the DOS R/O attribute. */
622             file_attributes |= FILE_ATTRIBUTE_READONLY;
623           /* The file attributes are needed for later use in, e.g. fchmod. */
624           pc.file_attributes (file_attributes);
625           /* Never set the WRITE_DAC flag here.  Calls to fstat may return
626              wrong st_ctime information after calls to fchmod, fchown, etc
627              because Windows only guarantees the update of metadata when
628              the handle is closed or flushed.  However, flushing the file
629              on every fstat to enforce POSIXy stat behaviour is excessivly
630              slow, compared to an extra open/close to change the file's
631              security descriptor. */
632         }
633     }
634
635   status = NtCreateFile (&fh, access, &attr, &io, NULL, file_attributes, shared,
636                          create_disposition, options, p, plen);
637   if (!NT_SUCCESS (status))
638     {
639       /* Trying to create a directory should return EISDIR, not ENOENT. */
640       PUNICODE_STRING upath = pc.get_nt_native_path ();
641       if (status == STATUS_OBJECT_NAME_INVALID && (flags & O_CREAT)
642           && upath->Buffer[upath->Length / sizeof (WCHAR) - 1] == '\\')
643         set_errno (EISDIR);
644       else
645         __seterrno_from_nt_status (status);
646       if (!nohandle ())
647         goto done;
648    }
649
650   /* Always create files using a NULL SD.  Create correct permission bits
651      afterwards, maintaining the owner and group information just like chmod.
652
653      This is done for two reasons.
654
655      On Windows filesystems we need to create the file with default
656      permissions to allow inheriting ACEs.  When providing an explicit DACL
657      in calls to [Nt]CreateFile, the created file will not inherit default
658      permissions from the parent object.  This breaks not only Windows
659      inheritance, but also POSIX ACL inheritance.
660
661      Another reason to do this are remote shares.  Files on a remote share
662      are created as the user used for authentication.  In a domain that's
663      usually the user you're logged in as.  Outside of a domain you're
664      authenticating using a local user account on the sharing machine.
665      If the SIDs of the client machine are used, that's entirely
666      unexpected behaviour.  Doing it like we do here creates the expected SD
667      in a domain as well as on standalone servers.
668      This is the result of a discussion on the samba-technical list, starting at
669      http://lists.samba.org/archive/samba-technical/2008-July/060247.html */
670   if (io.Information == FILE_CREATED && has_acls ())
671     set_file_attribute (fh, pc, ILLEGAL_UID, ILLEGAL_GID, S_JUSTCREATED | mode);
672
673   /* If you O_TRUNC a file on Linux, the data is truncated, but the EAs are
674      preserved.  If you open a file on Windows with FILE_OVERWRITE{_IF} or
675      FILE_SUPERSEDE, all streams are truncated, including the EAs.  So we don't
676      use the FILE_OVERWRITE{_IF} flags, but instead just open the file and set
677      the size of the data stream explicitely to 0.  Apart from being more Linux
678      compatible, this implementation has the pleasant side-effect to be more
679      than 5% faster than using FILE_OVERWRITE{_IF} (tested on W7 32 bit). */
680   if ((flags & O_TRUNC)
681       && (flags & O_ACCMODE) != O_RDONLY
682       && io.Information != FILE_CREATED
683       && get_device () == FH_FS)
684     {
685       FILE_END_OF_FILE_INFORMATION feofi = { EndOfFile:{ QuadPart:0 } };
686       status = NtSetInformationFile (fh, &io, &feofi, sizeof feofi,
687                                      FileEndOfFileInformation);
688       /* In theory, truncating the file should never fail, since the opened
689          handle has FILE_WRITE_DATA permissions, which is all you need to
690          be allowed to truncate a file.  Better safe than sorry. */
691       if (!NT_SUCCESS (status))
692         {
693           __seterrno_from_nt_status (status);
694           NtClose (fh);
695           goto done;
696         }
697     }
698
699   set_io_handle (fh);
700   set_flags (flags, pc.binmode ());
701
702   res = 1;
703   set_open_status ();
704 done:
705   debug_printf ("%x = NtCreateFile "
706                 "(%p, %x, %S, io, NULL, %x, %x, %x, %x, NULL, 0)",
707                 status, fh, access, pc.get_nt_native_path (), file_attributes,
708                 shared, create_disposition, options);
709
710   syscall_printf ("%d = fhandler_base::open(%S, %p)",
711                   res, pc.get_nt_native_path (), flags);
712   return res;
713 }
714
715 /* states:
716    open buffer in binary mode?  Just do the read.
717
718    open buffer in text mode?  Scan buffer for control zs and handle
719    the first one found.  Then scan buffer, converting every \r\n into
720    an \n.  If last char is an \r, look ahead one more char, if \n then
721    modify \r, if not, remember char.
722 */
723 void __stdcall
724 fhandler_base::read (void *in_ptr, size_t& len)
725 {
726   char *ptr = (char *) in_ptr;
727   ssize_t copied_chars = get_readahead_into_buffer (ptr, len);
728
729   if (copied_chars)
730     {
731       len = (size_t) copied_chars;
732       goto out;
733     }
734
735   len -= copied_chars;
736   if (!len)
737     {
738       len = (size_t) copied_chars;
739       goto out;
740     }
741
742   raw_read (ptr + copied_chars, len);
743   if (!copied_chars)
744     /* nothing */;
745   else if ((ssize_t) len > 0)
746     len += copied_chars;
747   else
748     len = copied_chars;
749
750   if (rbinary () || (ssize_t) len <= 0)
751     goto out;
752
753   /* Scan buffer and turn \r\n into \n */
754   char *src, *dst, *end;
755   src = (char *) ptr;
756   dst = (char *) ptr;
757   end = src + len - 1;
758
759   /* Read up to the last but one char - the last char needs special handling */
760   while (src < end)
761     {
762       if (*src == '\r' && src[1] == '\n')
763         src++;
764       *dst++ = *src++;
765     }
766
767   /* If not beyond end and last char is a '\r' then read one more
768      to see if we should translate this one too */
769   if (src > end)
770     /* nothing */;
771   else if (*src != '\r')
772     *dst++ = *src;
773   else
774     {
775       char c1;
776       size_t c1len = 1;
777       raw_read (&c1, c1len);
778       if (c1len <= 0)
779         /* nothing */;
780       else if (c1 == '\n')
781         *dst++ = '\n';
782       else
783         {
784           set_readahead_valid (1, c1);
785           *dst++ = *src;
786         }
787     }
788
789   len = dst - (char *) ptr;
790
791 #ifndef NOSTRACE
792   if (strace.active ())
793     {
794       char buf[16 * 6 + 1];
795       char *p = buf;
796
797       for (int i = 0; i < copied_chars && i < 16; ++i)
798         {
799           unsigned char c = ((unsigned char *) ptr)[i];
800           __small_sprintf (p, " %c", c);
801           p += strlen (p);
802         }
803       *p = '\0';
804       debug_printf ("read %d bytes (%s%s)", copied_chars, buf,
805                     copied_chars > 16 ? " ..." : "");
806     }
807 #endif
808
809 out:
810   debug_printf ("returning %d, %s mode", len, rbinary () ? "binary" : "text");
811 }
812
813 ssize_t __stdcall
814 fhandler_base::write (const void *ptr, size_t len)
815 {
816   int res;
817   IO_STATUS_BLOCK io;
818   FILE_POSITION_INFORMATION fpi;
819   FILE_STANDARD_INFORMATION fsi;
820
821   if (did_lseek ())
822     {
823       did_lseek (false); /* don't do it again */
824
825       if (!(get_flags () & O_APPEND)
826           && NT_SUCCESS (NtQueryInformationFile (get_output_handle (),
827                                                  &io, &fsi, sizeof fsi,
828                                                  FileStandardInformation))
829           && NT_SUCCESS (NtQueryInformationFile (get_output_handle (),
830                                                  &io, &fpi, sizeof fpi,
831                                                  FilePositionInformation))
832           && fpi.CurrentByteOffset.QuadPart
833              >= fsi.EndOfFile.QuadPart + (128 * 1024)
834           && (pc.fs_flags () & FILE_SUPPORTS_SPARSE_FILES))
835         {
836           /* If the file system supports sparse files and the application
837              is writing after a long seek beyond EOF, convert the file to
838              a sparse file. */
839           NTSTATUS status;
840           status = NtFsControlFile (get_output_handle (), NULL, NULL, NULL,
841                                     &io, FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
842           syscall_printf ("%p = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
843                           status, pc.get_nt_native_path ());
844         }
845     }
846
847   if (wbinary ())
848     {
849       debug_printf ("binary write");
850       res = raw_write (ptr, len);
851     }
852   else
853     {
854       debug_printf ("text write");
855       /* This is the Microsoft/DJGPP way.  Still not ideal, but it's
856          compatible.
857          Modified slightly by CGF 2000-10-07 */
858
859       int left_in_data = len;
860       char *data = (char *)ptr;
861       res = 0;
862
863       while (left_in_data > 0)
864         {
865           char buf[CHUNK_SIZE + 1], *buf_ptr = buf;
866           int left_in_buf = CHUNK_SIZE;
867
868           while (left_in_buf > 0 && left_in_data > 0)
869             {
870               char ch = *data++;
871               if (ch == '\n')
872                 {
873                   *buf_ptr++ = '\r';
874                   left_in_buf--;
875                 }
876               *buf_ptr++ = ch;
877               left_in_buf--;
878               left_in_data--;
879               if (left_in_data > 0 && ch == '\r' && *data == '\n')
880                 {
881                   *buf_ptr++ = *data++;
882                   left_in_buf--;
883                   left_in_data--;
884                 }
885             }
886
887           /* We've got a buffer-full, or we're out of data.  Write it out */
888           int nbytes;
889           int want = buf_ptr - buf;
890           if ((nbytes = raw_write (buf, want)) == want)
891             {
892               /* Keep track of how much written not counting additional \r's */
893               res = data - (char *)ptr;
894               continue;
895             }
896
897           if (nbytes == -1)
898             res = -1;           /* Error */
899           else
900             res += nbytes;      /* Partial write.  Return total bytes written. */
901           break;                /* All done */
902         }
903     }
904
905   return res;
906 }
907
908 ssize_t __stdcall
909 fhandler_base::readv (const struct iovec *const iov, const int iovcnt,
910                       ssize_t tot)
911 {
912   assert (iov);
913   assert (iovcnt >= 1);
914
915   size_t len = tot;
916   if (iovcnt == 1)
917     {
918       len = iov->iov_len;
919       read (iov->iov_base, len);
920       return len;
921     }
922
923   if (tot == -1)                // i.e. if not pre-calculated by the caller.
924     {
925       len = 0;
926       const struct iovec *iovptr = iov + iovcnt;
927       do
928         {
929           iovptr -= 1;
930           len += iovptr->iov_len;
931         }
932       while (iovptr != iov);
933     }
934
935   if (!len)
936     return 0;
937
938   char *buf = (char *) malloc (len);
939
940   if (!buf)
941     {
942       set_errno (ENOMEM);
943       return -1;
944     }
945
946   read (buf, len);
947   ssize_t nbytes = (ssize_t) len;
948
949   const struct iovec *iovptr = iov;
950
951   char *p = buf;
952   while (nbytes > 0)
953     {
954       const int frag = min (nbytes, (ssize_t) iovptr->iov_len);
955       memcpy (iovptr->iov_base, p, frag);
956       p += frag;
957       iovptr += 1;
958       nbytes -= frag;
959     }
960
961   free (buf);
962   return len;
963 }
964
965 ssize_t __stdcall
966 fhandler_base::writev (const struct iovec *const iov, const int iovcnt,
967                        ssize_t tot)
968 {
969   assert (iov);
970   assert (iovcnt >= 1);
971
972   if (iovcnt == 1)
973     return write (iov->iov_base, iov->iov_len);
974
975   if (tot == -1)                // i.e. if not pre-calculated by the caller.
976     {
977       tot = 0;
978       const struct iovec *iovptr = iov + iovcnt;
979       do
980         {
981           iovptr -= 1;
982           tot += iovptr->iov_len;
983         }
984       while (iovptr != iov);
985     }
986
987   assert (tot >= 0);
988
989   if (tot == 0)
990     return 0;
991
992   char *const buf = (char *) malloc (tot);
993
994   if (!buf)
995     {
996       set_errno (ENOMEM);
997       return -1;
998     }
999
1000   char *bufptr = buf;
1001   const struct iovec *iovptr = iov;
1002   int nbytes = tot;
1003
1004   while (nbytes != 0)
1005     {
1006       const int frag = min (nbytes, (ssize_t) iovptr->iov_len);
1007       memcpy (bufptr, iovptr->iov_base, frag);
1008       bufptr += frag;
1009       iovptr += 1;
1010       nbytes -= frag;
1011     }
1012   ssize_t ret = write (buf, tot);
1013   free (buf);
1014   return ret;
1015 }
1016
1017 _off64_t
1018 fhandler_base::lseek (_off64_t offset, int whence)
1019 {
1020   NTSTATUS status;
1021   IO_STATUS_BLOCK io;
1022   FILE_POSITION_INFORMATION fpi;
1023   FILE_STANDARD_INFORMATION fsi;
1024
1025   /* Seeks on text files is tough, we rewind and read till we get to the
1026      right place.  */
1027
1028   if (whence != SEEK_CUR || offset != 0)
1029     {
1030       if (whence == SEEK_CUR)
1031         offset -= ralen - raixget;
1032       set_readahead_valid (0);
1033     }
1034
1035   switch (whence)
1036     {
1037     case SEEK_SET:
1038       fpi.CurrentByteOffset.QuadPart = offset;
1039       break;
1040     case SEEK_CUR:
1041       status = NtQueryInformationFile (get_handle (), &io, &fpi, sizeof fpi,
1042                                        FilePositionInformation);
1043       if (!NT_SUCCESS (status))
1044         {
1045           __seterrno_from_nt_status (status);
1046           return -1;
1047         }
1048       fpi.CurrentByteOffset.QuadPart += offset;
1049       break;
1050     default: /* SEEK_END */
1051       status = NtQueryInformationFile (get_handle (), &io, &fsi, sizeof fsi,
1052                                        FileStandardInformation);
1053       if (!NT_SUCCESS (status))
1054         {
1055           __seterrno_from_nt_status (status);
1056           return -1;
1057         }
1058       fpi.CurrentByteOffset.QuadPart = fsi.EndOfFile.QuadPart + offset;
1059       break;
1060     }
1061
1062   debug_printf ("setting file pointer to %U", fpi.CurrentByteOffset.QuadPart);
1063   status = NtSetInformationFile (get_handle (), &io, &fpi, sizeof fpi,
1064                                  FilePositionInformation);
1065   if (!NT_SUCCESS (status))
1066     {
1067       __seterrno_from_nt_status (status);
1068       return -1;
1069     }
1070   _off64_t res = fpi.CurrentByteOffset.QuadPart;
1071
1072   /* When next we write(), we will check to see if *this* seek went beyond
1073      the end of the file and if so, potentially sparsify the file. */
1074   did_lseek (true);
1075
1076   /* If this was a SEEK_CUR with offset 0, we still might have
1077      readahead that we have to take into account when calculating
1078      the actual position for the application.  */
1079   if (whence == SEEK_CUR)
1080     res -= ralen - raixget;
1081
1082   return res;
1083 }
1084
1085 ssize_t __stdcall
1086 fhandler_base::pread (void *, size_t, _off64_t)
1087 {
1088   set_errno (ESPIPE);
1089   return -1;
1090 }
1091
1092 ssize_t __stdcall
1093 fhandler_base::pwrite (void *, size_t, _off64_t)
1094 {
1095   set_errno (ESPIPE);
1096   return -1;
1097 }
1098
1099 int
1100 fhandler_base::close_with_arch ()
1101 {
1102   int res;
1103   fhandler_base *fh;
1104   if (usecount)
1105     {
1106       if (!--usecount)
1107         debug_printf ("closing passed in archetype, usecount %d", usecount);
1108       else
1109         {
1110           debug_printf ("not closing passed in archetype, usecount %d", usecount);
1111           return 0;
1112         }
1113       fh = this;
1114     }
1115   else if (!archetype)
1116     fh = this;
1117   else
1118     {
1119       cleanup ();
1120       if (archetype_usecount (-1) == 0)
1121         {
1122           debug_printf ("closing archetype");
1123           fh = archetype;
1124         }
1125       else
1126         {
1127           debug_printf ("not closing archetype");
1128           return 0;
1129         }
1130     }
1131
1132   res = fh->close ();
1133   if (archetype)
1134     {
1135       cygheap->fdtab.delete_archetype (archetype);
1136       archetype = NULL;
1137     }
1138   return res;
1139 }
1140
1141 int
1142 fhandler_base::close ()
1143 {
1144   int res = -1;
1145
1146   syscall_printf ("closing '%s' handle %p", get_name (), get_handle ());
1147   if (nohandle () || CloseHandle (get_handle ()))
1148     res = 0;
1149   else
1150     {
1151       paranoid_printf ("CloseHandle failed, %E");
1152       __seterrno ();
1153     }
1154   isclosed (true);
1155   return res;
1156 }
1157
1158 DWORD WINAPI
1159 flush_async_io (void *arg)
1160 {
1161   fhandler_base_overlapped *fh = (fhandler_base_overlapped *) arg;
1162   debug_only_printf ("waiting for %s I/O for %s",
1163                      (fh->get_access () & GENERIC_WRITE) ? "write" : "read",
1164                      fh->get_name ());
1165   SetEvent (fh->get_overlapped ()->hEvent); /* force has_ongoing_io to block */
1166   bool res = fh->has_ongoing_io ();
1167   debug_printf ("finished waiting for I/O from %s, res %d", fh->get_name (),
1168                 res);
1169   fh->close ();
1170   delete fh;
1171
1172   InterlockedDecrement (&fhandler_base_overlapped::asio_close_counter);
1173   SetEvent (fhandler_base_overlapped::asio_done);
1174
1175   _my_tls._ctinfo->auto_release ();
1176   return 0;
1177 }
1178
1179 void
1180 fhandler_base_overlapped::flush_all_async_io ()
1181 {
1182   while (asio_close_counter > 0)
1183     if (WaitForSingleObject (asio_done, INFINITE) != WAIT_OBJECT_0)
1184       {
1185         system_printf ("WaitForSingleObject failed, possible data loss in pipe, %E");
1186         break;
1187       }
1188   asio_close_counter = 0;
1189   if (asio_done)
1190     CloseHandle (asio_done);
1191 }
1192
1193 /* Start a thread to handle closing of overlapped asynchronous I/O since
1194    Windows amazingly does not seem to always flush I/O on close.  */
1195 void
1196 fhandler_base_overlapped::check_later ()
1197 {
1198   set_close_on_exec (true);
1199   char buf[MAX_PATH];
1200   if (!asio_done
1201       && !(asio_done = CreateEvent (&sec_none_nih, false, false,
1202                                     shared_name (buf, "asio",
1203                                                  GetCurrentProcessId ()))))
1204     api_fatal ("CreateEvent failed, %E");
1205
1206   InterlockedIncrement (&asio_close_counter);
1207   if (!new cygthread(flush_async_io, this, "flasio"))
1208     api_fatal ("couldn't create a thread to track async I/O, %E");
1209   debug_printf ("started thread to handle asynchronous closing for %s", get_name ());
1210 }
1211
1212 int
1213 fhandler_base_overlapped::close ()
1214 {
1215   int res;
1216   /* Need to treat non-blocking I/O specially because Windows appears to
1217      be brain-dead  */
1218   if (is_nonblocking () && has_ongoing_io ())
1219     {
1220       clone (HEAP_3_FHANDLER)->check_later ();
1221       res = 0;
1222     }
1223   else
1224     {
1225       destroy_overlapped ();
1226       res = fhandler_base::close ();
1227     }
1228   return res;
1229 }
1230
1231 int
1232 fhandler_base::ioctl (unsigned int cmd, void *buf)
1233 {
1234   int res;
1235
1236   switch (cmd)
1237     {
1238     case FIONBIO:
1239       set_nonblocking (*(int *) buf);
1240       res = 0;
1241       break;
1242     case FIONREAD:
1243     case TIOCSCTTY:
1244       set_errno (ENOTTY);
1245       res = -1;
1246       break;
1247     default:
1248       set_errno (EINVAL);
1249       res = -1;
1250       break;
1251     }
1252
1253   syscall_printf ("%d = ioctl(%x, %p)", res, cmd, buf);
1254   return res;
1255 }
1256
1257 int
1258 fhandler_base::lock (int, struct __flock64 *)
1259 {
1260   set_errno (EINVAL);
1261   return -1;
1262 }
1263
1264 int __stdcall
1265 fhandler_base::fstat (struct __stat64 *buf)
1266 {
1267   if (is_fs_special ())
1268     return fstat_fs (buf);
1269
1270   switch (get_device ())
1271     {
1272     case FH_PIPE:
1273       buf->st_mode = S_IFIFO | S_IRUSR | S_IWUSR;
1274       break;
1275     case FH_PIPEW:
1276       buf->st_mode = S_IFIFO | S_IWUSR;
1277       break;
1278     case FH_PIPER:
1279       buf->st_mode = S_IFIFO | S_IRUSR;
1280       break;
1281     case FH_FULL:
1282       buf->st_mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH;
1283       break;
1284     default:
1285       buf->st_mode = S_IFCHR | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH;
1286       break;
1287     }
1288
1289   buf->st_uid = geteuid32 ();
1290   buf->st_gid = getegid32 ();
1291   buf->st_nlink = 1;
1292   buf->st_blksize = PREFERRED_IO_BLKSIZE;
1293
1294   buf->st_ctim.tv_sec = 1164931200L;    /* Arbitrary value: 2006-12-01 */
1295   buf->st_ctim.tv_nsec = 0L;
1296   buf->st_birthtim = buf->st_ctim;
1297   buf->st_mtim.tv_sec = time (NULL);    /* Arbitrary value: current time,
1298                                            like Linux */
1299   buf->st_mtim.tv_nsec = 0L;
1300   buf->st_atim = buf->st_mtim;
1301
1302   return 0;
1303 }
1304
1305 int __stdcall
1306 fhandler_base::fstatvfs (struct statvfs *sfs)
1307 {
1308   /* If we hit this base implementation, it's some device in /dev.
1309      Just call statvfs on /dev for simplicity. */
1310   path_conv pc ("/dev", PC_KEEP_HANDLE);
1311   fhandler_disk_file fh (pc);
1312   return fh.fstatvfs (sfs);
1313 }
1314
1315 int
1316 fhandler_base::init (HANDLE f, DWORD a, mode_t bin)
1317 {
1318   set_io_handle (f);
1319   access = a;
1320   a &= GENERIC_READ | GENERIC_WRITE;
1321   int flags = 0;
1322   if (a == GENERIC_READ)
1323     flags = O_RDONLY;
1324   else if (a == GENERIC_WRITE)
1325     flags = O_WRONLY;
1326   else if (a == (GENERIC_READ | GENERIC_WRITE))
1327     flags = O_RDWR;
1328   set_flags (flags | bin);
1329   set_open_status ();
1330   debug_printf ("created new fhandler_base for handle %p, bin %d", f, rbinary ());
1331   return 1;
1332 }
1333
1334 int
1335 fhandler_base::dup (fhandler_base *child, int)
1336 {
1337   debug_printf ("in fhandler_base dup");
1338
1339   HANDLE nh;
1340   if (!nohandle () && !archetype)
1341     {
1342       if (!DuplicateHandle (GetCurrentProcess (), get_handle (),
1343                             GetCurrentProcess (), &nh,
1344                             0, TRUE, DUPLICATE_SAME_ACCESS))
1345         {
1346           debug_printf ("dup(%s) failed, handle %x, %E",
1347                         get_name (), get_handle ());
1348           __seterrno ();
1349           return -1;
1350         }
1351
1352       VerifyHandle (nh);
1353       child->set_io_handle (nh);
1354     }
1355   return 0;
1356 }
1357
1358 int
1359 fhandler_base_overlapped::dup (fhandler_base *child, int flags)
1360 {
1361   int res = fhandler_base::dup (child, flags) ||
1362             ((fhandler_base_overlapped *) child)->setup_overlapped ();
1363   return res;
1364 }
1365
1366 int fhandler_base::fcntl (int cmd, void *arg)
1367 {
1368   int res;
1369
1370   switch (cmd)
1371     {
1372     case F_GETFD:
1373       res = close_on_exec () ? FD_CLOEXEC : 0;
1374       break;
1375     case F_SETFD:
1376       set_close_on_exec (((int) arg & FD_CLOEXEC) ? 1 : 0);
1377       res = 0;
1378       break;
1379     case F_GETFL:
1380       res = get_flags ();
1381       debug_printf ("GETFL: %p", res);
1382       break;
1383     case F_SETFL:
1384       {
1385         /* Only O_APPEND, O_ASYNC and O_NONBLOCK/O_NDELAY are allowed.
1386            Each other flag will be ignored.
1387            Since O_ASYNC isn't defined in fcntl.h it's currently
1388            ignored as well.  */
1389         const int allowed_flags = O_APPEND | O_NONBLOCK_MASK;
1390         int new_flags = (int) arg & allowed_flags;
1391         /* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag.
1392            Set only the flag that has been passed in.  If both are set, just
1393            record O_NONBLOCK.   */
1394         if ((new_flags & OLD_O_NDELAY) && (new_flags & O_NONBLOCK))
1395           new_flags &= ~OLD_O_NDELAY;
1396         set_flags ((get_flags () & ~allowed_flags) | new_flags);
1397       }
1398       res = 0;
1399       break;
1400     default:
1401       set_errno (EINVAL);
1402       res = -1;
1403       break;
1404     }
1405   return res;
1406 }
1407
1408 /* Base terminal handlers.  These just return errors.  */
1409
1410 int
1411 fhandler_base::tcflush (int)
1412 {
1413   set_errno (ENOTTY);
1414   return -1;
1415 }
1416
1417 int
1418 fhandler_base::tcsendbreak (int)
1419 {
1420   set_errno (ENOTTY);
1421   return -1;
1422 }
1423
1424 int
1425 fhandler_base::tcdrain ()
1426 {
1427   set_errno (ENOTTY);
1428   return -1;
1429 }
1430
1431 int
1432 fhandler_base::tcflow (int)
1433 {
1434   set_errno (ENOTTY);
1435   return -1;
1436 }
1437
1438 int
1439 fhandler_base::tcsetattr (int, const struct termios *)
1440 {
1441   set_errno (ENOTTY);
1442   return -1;
1443 }
1444
1445 int
1446 fhandler_base::tcgetattr (struct termios *)
1447 {
1448   set_errno (ENOTTY);
1449   return -1;
1450 }
1451
1452 int
1453 fhandler_base::tcsetpgrp (const pid_t)
1454 {
1455   set_errno (ENOTTY);
1456   return -1;
1457 }
1458
1459 int
1460 fhandler_base::tcgetpgrp ()
1461 {
1462   set_errno (ENOTTY);
1463   return -1;
1464 }
1465
1466 int
1467 fhandler_base::tcgetsid ()
1468 {
1469   set_errno (ENOTTY);
1470   return -1;
1471 }
1472
1473 int
1474 fhandler_base::ptsname_r (char *, size_t)
1475 {
1476   set_errno (ENOTTY);
1477   return ENOTTY;
1478 }
1479
1480 /* Normal I/O constructor */
1481 fhandler_base::fhandler_base () :
1482   status (),
1483   open_status (),
1484   access (0),
1485   io_handle (NULL),
1486   ino (0),
1487   _refcnt (0),
1488   openflags (0),
1489   rabuf (NULL),
1490   ralen (0),
1491   raixget (0),
1492   raixput (0),
1493   rabuflen (0),
1494   unique_id (0),
1495   archetype (NULL),
1496   usecount (0)
1497 {
1498   isclosed (false);
1499 }
1500
1501 /* Normal I/O destructor */
1502 fhandler_base::~fhandler_base ()
1503 {
1504   if (rabuf)
1505     free (rabuf);
1506 }
1507
1508 /**********************************************************************/
1509 /* /dev/null */
1510
1511 fhandler_dev_null::fhandler_dev_null () :
1512         fhandler_base ()
1513 {
1514 }
1515
1516 void
1517 fhandler_base::set_no_inheritance (HANDLE &h, bool not_inheriting)
1518 {
1519   if (!SetHandleInformation (h, HANDLE_FLAG_INHERIT,
1520                              not_inheriting ? 0 : HANDLE_FLAG_INHERIT))
1521     debug_printf ("SetHandleInformation failed, %E");
1522 #ifdef DEBUGGING_AND_FDS_PROTECTED
1523   if (h)
1524     setclexec (oh, h, not_inheriting);
1525 #endif
1526 }
1527
1528 bool
1529 fhandler_base::fork_fixup (HANDLE parent, HANDLE &h, const char *name)
1530 {
1531   HANDLE oh = h;
1532   bool res = false;
1533   if (/* !is_socket () && */ !close_on_exec ())
1534     debug_printf ("handle %p already opened", h);
1535   else if (!DuplicateHandle (parent, h, GetCurrentProcess (), &h,
1536                              0, !close_on_exec (), DUPLICATE_SAME_ACCESS))
1537     system_printf ("%s - %E, handle %s<%p>", get_name (), name, h);
1538   else
1539     {
1540       if (oh != h)
1541         VerifyHandle (h);
1542       res = true;
1543     }
1544   return res;
1545 }
1546
1547 void
1548 fhandler_base::set_close_on_exec (bool val)
1549 {
1550   if (!nohandle ())
1551     set_no_inheritance (io_handle, val);
1552   close_on_exec (val);
1553   debug_printf ("set close_on_exec for %s to %d", get_name (), val);
1554 }
1555
1556 void
1557 fhandler_base::fixup_after_fork (HANDLE parent)
1558 {
1559   debug_printf ("inheriting '%s' from parent", get_name ());
1560   if (!nohandle ())
1561     fork_fixup (parent, io_handle, "io_handle");
1562   /* POSIX locks are not inherited across fork. */
1563   if (unique_id)
1564     del_my_locks (after_fork);
1565 }
1566
1567 void
1568 fhandler_base_overlapped::fixup_after_fork (HANDLE parent)
1569 {
1570   setup_overlapped ();
1571   fhandler_base::fixup_after_fork (parent);
1572 }
1573
1574 void
1575 fhandler_base::fixup_after_exec ()
1576 {
1577   debug_printf ("here for '%s'", get_name ());
1578   if (unique_id && close_on_exec ())
1579     del_my_locks (after_exec);
1580 }
1581 void
1582 fhandler_base_overlapped::fixup_after_exec ()
1583 {
1584   setup_overlapped ();
1585   fhandler_base::fixup_after_exec ();
1586 }
1587
1588 bool
1589 fhandler_base::is_nonblocking ()
1590 {
1591   return (openflags & O_NONBLOCK_MASK) != 0;
1592 }
1593
1594 void
1595 fhandler_base::set_nonblocking (int yes)
1596 {
1597   int current = openflags & O_NONBLOCK_MASK;
1598   int new_flags = yes ? (!current ? O_NONBLOCK : current) : 0;
1599   openflags = (openflags & ~O_NONBLOCK_MASK) | new_flags;
1600 }
1601
1602 int
1603 fhandler_base::mkdir (mode_t)
1604 {
1605   if (exists ())
1606     set_errno (EEXIST);
1607   else
1608     set_errno (EROFS);
1609   return -1;
1610 }
1611
1612 int
1613 fhandler_base::rmdir ()
1614 {
1615   if (!exists ())
1616     set_errno (ENOENT);
1617   else if (!pc.isdir ())
1618     set_errno (ENOTDIR);
1619   else
1620     set_errno (EROFS);
1621   return -1;
1622 }
1623
1624 DIR *
1625 fhandler_base::opendir (int fd)
1626 {
1627   set_errno (ENOTDIR);
1628   return NULL;
1629 }
1630
1631 int
1632 fhandler_base::readdir (DIR *, dirent *)
1633 {
1634   return ENOTDIR;
1635 }
1636
1637 long
1638 fhandler_base::telldir (DIR *)
1639 {
1640   set_errno (ENOTDIR);
1641   return -1;
1642 }
1643
1644 void
1645 fhandler_base::seekdir (DIR *, long)
1646 {
1647   set_errno (ENOTDIR);
1648 }
1649
1650 void
1651 fhandler_base::rewinddir (DIR *)
1652 {
1653   set_errno (ENOTDIR);
1654 }
1655
1656 int
1657 fhandler_base::closedir (DIR *)
1658 {
1659   set_errno (ENOTDIR);
1660   return -1;
1661 }
1662
1663 int
1664 fhandler_base::fchmod (mode_t mode)
1665 {
1666   extern int chmod_device (path_conv& pc, mode_t mode);
1667   if (pc.is_fs_special ())
1668     return chmod_device (pc, mode);
1669   /* By default, just succeeds. */
1670   return 0;
1671 }
1672
1673 int
1674 fhandler_base::fchown (__uid32_t uid, __gid32_t gid)
1675 {
1676   if (pc.is_fs_special ())
1677     return ((fhandler_disk_file *) this)->fhandler_disk_file::fchown (uid, gid);
1678   /* By default, just succeeds. */
1679   return 0;
1680 }
1681
1682 int
1683 fhandler_base::facl (int cmd, int nentries, __aclent32_t *aclbufp)
1684 {
1685   int res = -1;
1686   switch (cmd)
1687     {
1688       case SETACL:
1689         /* By default, just succeeds. */
1690         res = 0;
1691         break;
1692       case GETACL:
1693         if (!aclbufp)
1694           set_errno(EFAULT);
1695         else if (nentries < MIN_ACL_ENTRIES)
1696           set_errno (ENOSPC);
1697         else
1698           {
1699             aclbufp[0].a_type = USER_OBJ;
1700             aclbufp[0].a_id = myself->uid;
1701             aclbufp[0].a_perm = (S_IRUSR | S_IWUSR) >> 6;
1702             aclbufp[1].a_type = GROUP_OBJ;
1703             aclbufp[1].a_id = myself->gid;
1704             aclbufp[1].a_perm = (S_IRGRP | S_IWGRP) >> 3;
1705             aclbufp[2].a_type = OTHER_OBJ;
1706             aclbufp[2].a_id = ILLEGAL_GID;
1707             aclbufp[2].a_perm = S_IROTH | S_IWOTH;
1708             aclbufp[3].a_type = CLASS_OBJ;
1709             aclbufp[3].a_id = ILLEGAL_GID;
1710             aclbufp[3].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
1711             res = MIN_ACL_ENTRIES;
1712           }
1713         break;
1714       case GETACLCNT:
1715         res = MIN_ACL_ENTRIES;
1716         break;
1717       default:
1718         set_errno (EINVAL);
1719         break;
1720     }
1721   return res;
1722 }
1723
1724 ssize_t
1725 fhandler_base::fgetxattr (const char *name, void *value, size_t size)
1726 {
1727   set_errno (ENOTSUP);
1728   return -1;
1729 }
1730
1731 int
1732 fhandler_base::fsetxattr (const char *name, const void *value, size_t size,
1733                           int flags)
1734 {
1735   set_errno (ENOTSUP);
1736   return -1;
1737 }
1738
1739 int
1740 fhandler_base::fadvise (_off64_t offset, _off64_t length, int advice)
1741 {
1742   set_errno (EINVAL);
1743   return -1;
1744 }
1745
1746 int
1747 fhandler_base::ftruncate (_off64_t length, bool allow_truncate)
1748 {
1749   set_errno (EINVAL);
1750   return -1;
1751 }
1752
1753 int
1754 fhandler_base::link (const char *newpath)
1755 {
1756   set_errno (EPERM);
1757   return -1;
1758 }
1759
1760 int
1761 fhandler_base::utimens (const struct timespec *tvp)
1762 {
1763   if (is_fs_special ())
1764     return utimens_fs (tvp);
1765
1766   set_errno (EINVAL);
1767   return -1;
1768 }
1769
1770 int
1771 fhandler_base::fsync ()
1772 {
1773   if (!get_handle () || nohandle ())
1774     {
1775       set_errno (EINVAL);
1776       return -1;
1777     }
1778   if (pc.isdir ()) /* Just succeed. */
1779     return 0;
1780   if (FlushFileBuffers (get_handle ()))
1781     return 0;
1782
1783   /* Ignore ERROR_INVALID_FUNCTION because FlushFileBuffers() always fails
1784      with this code on raw devices which are unbuffered by default.  */
1785   DWORD errcode = GetLastError();
1786   if (errcode == ERROR_INVALID_FUNCTION)
1787     return 0;
1788
1789   __seterrno_from_win_error (errcode);
1790   return -1;
1791 }
1792
1793 int
1794 fhandler_base::fpathconf (int v)
1795 {
1796   int ret;
1797
1798   switch (v)
1799     {
1800     case _PC_LINK_MAX:
1801       return pc.fs_is_ntfs () || pc.fs_is_samba () || pc.fs_is_nfs ()
1802              ? LINK_MAX : 1;
1803     case _PC_MAX_CANON:
1804       if (is_tty ())
1805         return MAX_CANON;
1806       set_errno (EINVAL);
1807       break;
1808     case _PC_MAX_INPUT:
1809       if (is_tty ())
1810         return MAX_INPUT;
1811       set_errno (EINVAL);
1812       break;
1813     case _PC_NAME_MAX:
1814       /* NAME_MAX is without trailing \0 */
1815       if (!pc.isdir ())
1816         return NAME_MAX;
1817       ret = NT_MAX_PATH - strlen (get_name ()) - 2;
1818       return ret < 0 ? 0 : ret > NAME_MAX ? NAME_MAX : ret;
1819     case _PC_PATH_MAX:
1820       /* PATH_MAX is with trailing \0 */
1821       if (!pc.isdir ())
1822         return PATH_MAX;
1823       ret = NT_MAX_PATH - strlen (get_name ()) - 1;
1824       return ret < 0 ? 0 : ret > PATH_MAX ? PATH_MAX : ret;
1825     case _PC_PIPE_BUF:
1826       if (pc.isdir ()
1827           || get_device () == FH_FIFO || get_device () == FH_PIPE
1828           || get_device () == FH_PIPER || get_device () == FH_PIPEW)
1829         return PIPE_BUF;
1830       set_errno (EINVAL);
1831       break;
1832     case _PC_CHOWN_RESTRICTED:
1833       return 1;
1834     case _PC_NO_TRUNC:
1835       return 1;
1836     case _PC_VDISABLE:
1837       if (is_tty ())
1838         return _POSIX_VDISABLE;
1839       set_errno (EINVAL);
1840       break;
1841     case _PC_ASYNC_IO:
1842     case _PC_PRIO_IO:
1843       break;
1844     case _PC_SYNC_IO:
1845       return 1;
1846     case _PC_FILESIZEBITS:
1847       return FILESIZEBITS;
1848     case _PC_2_SYMLINKS:
1849       return 1;
1850     case _PC_SYMLINK_MAX:
1851       return SYMLINK_MAX;
1852     case _PC_POSIX_PERMISSIONS:
1853     case _PC_POSIX_SECURITY:
1854       if (get_device () == FH_FS)
1855         return pc.has_acls () || pc.fs_is_nfs ();
1856       set_errno (EINVAL);
1857       break;
1858     default:
1859       set_errno (EINVAL);
1860       break;
1861     }
1862   return -1;
1863 }
1864
1865 /* Overlapped I/O */
1866
1867 int __stdcall __attribute__ ((regparm (1)))
1868 fhandler_base_overlapped::setup_overlapped ()
1869 {
1870   OVERLAPPED *ov = get_overlapped_buffer ();
1871   memset (ov, 0, sizeof (*ov));
1872   set_overlapped (ov);
1873   ov->hEvent = CreateEvent (&sec_none_nih, true, true, NULL);
1874   io_pending = false;
1875   return ov->hEvent ? 0 : -1;
1876 }
1877
1878 void __stdcall __attribute__ ((regparm (1)))
1879 fhandler_base_overlapped::destroy_overlapped ()
1880 {
1881   OVERLAPPED *ov = get_overlapped ();
1882   if (ov && ov->hEvent)
1883     {
1884       CloseHandle (ov->hEvent);
1885       ov->hEvent = NULL;
1886     }
1887   io_pending = false;
1888   get_overlapped () = NULL;
1889 }
1890
1891 bool __stdcall __attribute__ ((regparm (1)))
1892 fhandler_base_overlapped::has_ongoing_io ()
1893 {
1894   if (!io_pending)
1895     return false;
1896
1897   if (!IsEventSignalled (get_overlapped ()->hEvent))
1898     return true;
1899   io_pending = false;
1900   DWORD nbytes;
1901   GetOverlappedResult (get_output_handle (), get_overlapped (), &nbytes, true);
1902   return false;
1903 }
1904
1905 fhandler_base_overlapped::wait_return __stdcall __attribute__ ((regparm (3)))
1906 fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *bytes, bool nonblocking, DWORD len)
1907 {
1908   if (!get_overlapped ())
1909     return inres ? overlapped_success : overlapped_error;
1910
1911   wait_return res = overlapped_unknown;
1912   DWORD err;
1913   if (inres)
1914     /* handle below */;
1915   else if ((err = GetLastError ()) != ERROR_IO_PENDING)
1916     res = overlapped_error;
1917   else if (!nonblocking)
1918     /* handle below */;
1919   else if (!writing)
1920     SetEvent (get_overlapped ()->hEvent);       /* Force immediate WFMO return */
1921   else
1922     {
1923       *bytes = len;                             /* Assume that this worked */
1924       io_pending = true;                        /*  but don't allow subsequent */
1925       res = overlapped_success;                 /*  writes until completed */
1926     }
1927   if (res == overlapped_unknown)
1928     {
1929       DWORD wfres = cygwait (get_overlapped ()->hEvent);
1930       HANDLE h = writing ? get_output_handle () : get_handle ();
1931       BOOL wores;
1932       if (isclosed ())
1933         wores = 0;      /* closed in another thread or via signal handler */
1934       else
1935         {
1936           /* Cancelling here to prevent races.  It's possible that the I/O has
1937              completed already, in which case this is a no-op.  Otherwise,
1938              WFMO returned because 1) This is a non-blocking call, 2) a signal
1939              arrived, or 3) the operation was cancelled.  These cases may be
1940              overridden by the return of GetOverlappedResult which could detect
1941              that I/O completion occurred.  */
1942           CancelIo (h);
1943           wores = GetOverlappedResult (h, get_overlapped (), bytes, false);
1944           err = GetLastError ();
1945           ResetEvent (get_overlapped ()->hEvent);       /* Probably not needed but CYA */
1946           debug_printf ("wfres %d, wores %d, bytes %u", wfres, wores, *bytes);
1947         }
1948       if (wores)
1949         res = overlapped_success;       /* operation succeeded */
1950       else if (wfres == WAIT_OBJECT_0 + 1)
1951         {
1952           err = ERROR_INVALID_AT_INTERRUPT_TIME; /* forces an EINTR below */
1953           debug_printf ("signal");
1954           res = overlapped_error;
1955         }
1956       else if (nonblocking)
1957         res = overlapped_nonblocking_no_data;   /* more handling below */
1958       else if (wfres == WAIT_OBJECT_0 + 2)
1959         pthread::static_cancel_self ();         /* never returns */
1960       else
1961         {
1962           debug_printf ("GetOverLappedResult failed, h %p, bytes %u, %E", h, *bytes);
1963           res = overlapped_error;
1964         }
1965     }
1966
1967   if (res == overlapped_success)
1968     debug_printf ("normal %s, %u bytes", writing ? "write" : "read", *bytes);
1969   else if (res == overlapped_nonblocking_no_data)
1970     {
1971       *bytes = (DWORD) -1;
1972       set_errno (EAGAIN);
1973       debug_printf ("no data to read for nonblocking I/O");
1974     }
1975   else if (err == ERROR_HANDLE_EOF || err == ERROR_BROKEN_PIPE)
1976     {
1977       debug_printf ("EOF, %E");
1978       *bytes = 0;
1979       res = overlapped_success;
1980       if (writing && err == ERROR_BROKEN_PIPE)
1981         raise (SIGPIPE);
1982     }
1983   else
1984     {
1985       debug_printf ("res %u, Win32 Error %u", (unsigned) res, err);
1986       *bytes = (DWORD) -1;
1987       __seterrno_from_win_error (err);
1988       if (writing && err == ERROR_NO_DATA)
1989         raise (SIGPIPE);
1990     }
1991
1992   return res;
1993 }
1994
1995 void __stdcall __attribute__ ((regparm (3)))
1996 fhandler_base_overlapped::raw_read (void *ptr, size_t& len)
1997 {
1998   DWORD nbytes;
1999   bool keep_looping;
2000   do
2001     {
2002       bool res = ReadFile (get_handle (), ptr, len, &nbytes,
2003                            get_overlapped ());
2004       switch (wait_overlapped (res, false, &nbytes, is_nonblocking ()))
2005         {
2006         default:        /* Added to quiet gcc */
2007         case overlapped_success:
2008         case overlapped_error:
2009           keep_looping = false;
2010           break;
2011         }
2012     }
2013   while (keep_looping);
2014   len = (size_t) nbytes;
2015 }
2016
2017 ssize_t __stdcall __attribute__ ((regparm (3)))
2018 fhandler_base_overlapped::raw_write (const void *ptr, size_t len)
2019 {
2020   size_t nbytes;
2021   if (has_ongoing_io ())
2022     {
2023       set_errno (EAGAIN);
2024       nbytes = (DWORD) -1;
2025     }
2026   else
2027     {
2028       size_t chunk;
2029       if (!max_atomic_write || len < max_atomic_write)
2030         chunk = len;
2031       else if (is_nonblocking ())
2032         chunk = len = max_atomic_write;
2033       else
2034         chunk = max_atomic_write;
2035
2036       nbytes = 0;
2037       DWORD nbytes_now = 0;
2038       /* Write to fd in smaller chunks, accumlating a total.
2039          If there's an error, just return the accumulated total
2040          unless the first write fails, in which case return value
2041          from wait_overlapped(). */
2042       while (nbytes < len)
2043         {
2044           size_t left = len - nbytes;
2045           size_t len1;
2046           if (left > chunk)
2047             len1 = chunk;
2048           else
2049             len1 = left;
2050           bool res = WriteFile (get_output_handle (), ptr, len1, &nbytes_now,
2051                                 get_overlapped ());
2052           switch (wait_overlapped (res, true, &nbytes_now,
2053                                    is_nonblocking (), len1))
2054             {
2055             case overlapped_success:
2056               ptr = ((char *) ptr) + chunk;
2057               nbytes += nbytes_now;
2058               /* fall through intentionally */
2059             case overlapped_error:
2060               len = 0;          /* terminate loop */
2061             case overlapped_unknown:
2062             case overlapped_nonblocking_no_data:
2063               break;
2064             }
2065         }
2066       if (!nbytes)
2067         nbytes = nbytes_now;
2068     }
2069   return nbytes;
2070 }