OSDN Git Service

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