OSDN Git Service

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