OSDN Git Service

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