1 /* fhandler.cc. See console.cc for fhandler_console functions.
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
18 #include "perprocess.h"
20 #include "cygwin/version.h"
31 #include "shared_info.h"
32 #include <asm/socket.h>
34 #define MAX_OVERLAPPED_WRITE_LEN (64 * 1024 * 1024)
35 #define MIN_OVERLAPPED_WRITE_LEN (1 * 1024 * 1024)
37 static const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
39 struct __cygwin_perfile *perfile_table;
41 HANDLE NO_COPY fhandler_base_overlapped::asio_done;
42 LONG NO_COPY fhandler_base_overlapped::asio_close_counter;
45 fhandler_base::reset (const fhandler_base *from)
56 fhandler_base::puts_readahead (const char *s, size_t len)
59 while ((len == (size_t) -1 ? *s : len--)
60 && (success = put_readahead (*s++) > 0))
66 fhandler_base::put_readahead (char value)
69 if (raixput < rabuflen)
71 else if ((newrabuf = (char *) realloc (rabuf, rabuflen += 32)))
76 rabuf[raixput++] = value;
82 fhandler_base::get_readahead ()
86 chret = ((unsigned char) rabuf[raixget++]) & 0xff;
87 /* FIXME - not thread safe */
89 raixget = raixput = ralen = 0;
94 fhandler_base::peek_readahead (int queryput)
97 if (!queryput && raixget < ralen)
98 chret = ((unsigned char) rabuf[raixget]) & 0xff;
99 else if (queryput && raixput > 0)
100 chret = ((unsigned char) rabuf[raixput - 1]) & 0xff;
105 fhandler_base::set_readahead_valid (int val, int ch)
108 ralen = raixget = raixput = 0;
114 fhandler_base::eat_readahead (int n)
121 if ((int) (ralen -= n) < 0)
124 if (raixget >= ralen)
125 raixget = raixput = ralen = 0;
126 else if (raixput > ralen)
134 fhandler_base::get_readahead_into_buffer (char *buf, size_t buflen)
137 int copied_chars = 0;
140 if ((ch = get_readahead ()) < 0)
144 buf[copied_chars++] = (unsigned char)(ch & 0xff);
151 /* Record the file name. and name hash */
153 fhandler_base::set_name (path_conv &in_pc)
158 char *fhandler_base::get_proc_fd_name (char *buf)
161 return strcpy (buf, get_name ());
163 return strcpy (buf, dev ().name);
164 return strcpy (buf, "");
167 /* Detect if we are sitting at EOF for conditions where Windows
168 returns an error but UNIX doesn't. */
173 FILE_POSITION_INFORMATION fpi;
174 FILE_STANDARD_INFORMATION fsi;
176 if (NT_SUCCESS (NtQueryInformationFile (h, &io, &fsi, sizeof fsi,
177 FileStandardInformation))
178 && NT_SUCCESS (NtQueryInformationFile (h, &io, &fpi, sizeof fpi,
179 FilePositionInformation))
180 && fsi.EndOfFile.QuadPart == fpi.CurrentByteOffset.QuadPart)
186 fhandler_base::set_flags (int flags, int supplied_bin)
190 debug_printf ("flags %p, supplied_bin %p", flags, supplied_bin);
191 if ((bin = flags & (O_BINARY | O_TEXT)))
192 debug_printf ("O_TEXT/O_BINARY set in flags %p", bin);
193 else if (rbinset () && wbinset ())
194 bin = rbinary () ? O_BINARY : O_TEXT; // FIXME: Not quite right
195 else if ((fmode = get_default_fmode (flags)) & O_BINARY)
197 else if (fmode & O_TEXT)
199 else if (supplied_bin)
202 bin = wbinary () || rbinary () ? O_BINARY : O_TEXT;
204 openflags = flags | bin;
207 rbinary (bin ? true : false);
208 wbinary (bin ? true : false);
209 syscall_printf ("filemode set to %s", bin ? "binary" : "text");
212 /* Normal file i/o handlers. */
214 /* Cover function to ReadFile to achieve (as much as possible) Posix style
215 semantics and use of errno. */
217 fhandler_base::raw_read (void *ptr, size_t& ulen)
219 #define bytes_read ulen
221 int try_noreserve = 1;
226 BOOL res = ReadFile (get_handle (), ptr, len, (DWORD *) &ulen, NULL);
229 /* Some errors are not really errors. Detect such cases here. */
231 DWORD errcode = GetLastError ();
234 case ERROR_BROKEN_PIPE:
235 /* This is really EOF. */
238 case ERROR_MORE_DATA:
239 /* `bytes_read' is supposedly valid. */
242 if (is_at_eof (get_handle ()))
250 switch (mmap_is_attached_or_noreserve (ptr, len))
252 case MMAP_NORESERVE_COMMITED:
254 case MMAP_RAISE_SIGBUS:
261 case ERROR_INVALID_FUNCTION:
262 case ERROR_INVALID_PARAMETER:
263 case ERROR_INVALID_HANDLE:
267 bytes_read = (size_t) -1;
271 syscall_printf ("ReadFile %s(%p) failed, %E", get_name (), get_handle ());
272 __seterrno_from_win_error (errcode);
273 bytes_read = (size_t) -1;
280 /* Cover function to WriteFile to provide Posix interface and semantics
281 (as much as possible). */
283 fhandler_base::raw_write (const void *ptr, size_t len)
287 static _RDATA LARGE_INTEGER off_current =
288 { QuadPart:FILE_USE_FILE_POINTER_POSITION };
289 static _RDATA LARGE_INTEGER off_append =
290 { QuadPart:FILE_WRITE_TO_END_OF_FILE };
292 status = NtWriteFile (get_output_handle (), NULL, NULL, NULL, &io,
294 (get_flags () & O_APPEND) ? &off_append : &off_current,
296 if (!NT_SUCCESS (status))
298 __seterrno_from_nt_status (status);
299 if (get_errno () == EPIPE)
303 return io.Information;
307 fhandler_base::get_default_fmode (int flags)
312 size_t nlen = strlen (get_name ());
313 unsigned accflags = (flags & O_ACCMODE);
314 for (__cygwin_perfile *pf = perfile_table; pf->name; pf++)
315 if (!*pf->name && (pf->flags & O_ACCMODE) == accflags)
317 fmode = pf->flags & ~O_ACCMODE;
322 size_t pflen = strlen (pf->name);
323 const char *stem = get_name () + nlen - pflen;
324 if (pflen > nlen || (stem != get_name () && !isdirsep (stem[-1])))
326 else if ((pf->flags & O_ACCMODE) == accflags
327 && pathmatch (stem, pf->name, !!pc.objcaseinsensitive ()))
329 fmode = pf->flags & ~O_ACCMODE;
338 fhandler_base::device_access_denied (int flags)
344 if (flags & (O_WRONLY | O_APPEND))
349 return fhaccess (mode, true);
353 fhandler_base::fhaccess (int flags, bool effective)
358 set_errno (error ());
368 if (!(flags & (R_OK | W_OK | X_OK)))
371 if (is_fs_special ())
373 else if (has_attribute (FILE_ATTRIBUTE_READONLY) && (flags & W_OK)
376 else if (has_acls ())
378 res = check_file_access (pc, flags, effective);
381 else if (get_device () == FH_REGISTRY && open (O_RDONLY, 0) && get_handle ())
383 res = check_registry_access (get_handle (), flags, effective);
394 if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid))
396 if (!(st.st_mode & S_IRUSR))
399 else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid))
401 if (!(st.st_mode & S_IRGRP))
404 else if (!(st.st_mode & S_IROTH))
410 if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid))
412 if (!(st.st_mode & S_IWUSR))
415 else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid))
417 if (!(st.st_mode & S_IWGRP))
420 else if (!(st.st_mode & S_IWOTH))
426 if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid))
428 if (!(st.st_mode & S_IXUSR))
431 else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid))
433 if (!(st.st_mode & S_IXGRP))
436 else if (!(st.st_mode & S_IXOTH))
446 if (!res && (flags & W_OK) && get_device () == FH_FS
447 && (pc.fs_flags () & FILE_READ_ONLY_VOLUME))
452 debug_printf ("returning %d", res);
457 fhandler_base::open_with_arch (int flags, mode_t mode)
460 if (!(res = (archetype && archetype->io_handle)
461 || open (flags, (mode & 07777) & ~cygheap->umask)))
468 if (!archetype->get_io_handle ())
471 archetype_usecount (1);
472 archetype->archetype = NULL;
478 /* Preserve any name (like /dev/tty) derived from build_fh_pc. */
483 name = (char *) alloca (strlen (get_name ()) + 1);
484 strcpy (name, get_name ());
486 fhandler_base *arch = archetype;
487 archetype->copyto (this);
491 archetype_usecount (1);
497 close_on_exec (flags & O_CLOEXEC);
501 /* Open system call handler function. */
503 fhandler_base::open (int flags, mode_t mode)
507 ULONG file_attributes = 0;
508 ULONG shared = (get_major () == DEV_TAPE_MAJOR ? 0 : FILE_SHARE_VALID_FLAGS);
509 ULONG create_disposition;
510 OBJECT_ATTRIBUTES attr;
513 PFILE_FULL_EA_INFORMATION p = NULL;
516 syscall_printf ("(%S, %p)", pc.get_nt_native_path (), flags);
518 pc.get_object_attr (attr, *sec_none_cloexec (flags));
520 options = FILE_OPEN_FOR_BACKUP_INTENT;
521 switch (query_open ())
523 case query_read_control:
524 access = READ_CONTROL;
526 case query_read_attributes:
527 access = READ_CONTROL | FILE_READ_ATTRIBUTES;
529 case query_write_control:
530 access = READ_CONTROL | WRITE_OWNER | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
532 case query_write_dac:
533 access = READ_CONTROL | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
535 case query_write_attributes:
536 access = READ_CONTROL | FILE_WRITE_ATTRIBUTES;
539 if ((flags & O_ACCMODE) == O_RDONLY)
540 access = GENERIC_READ;
541 else if ((flags & O_ACCMODE) == O_WRONLY)
542 access = GENERIC_WRITE | READ_CONTROL | FILE_READ_ATTRIBUTES;
544 access = GENERIC_READ | GENERIC_WRITE;
546 options |= FILE_WRITE_THROUGH;
547 if (flags & O_DIRECT)
548 options |= FILE_NO_INTERMEDIATE_BUFFERING;
549 if (get_major () != DEV_SERIAL_MAJOR && get_major () != DEV_TAPE_MAJOR)
551 options |= FILE_SYNCHRONOUS_IO_NONALERT;
552 access |= SYNCHRONIZE;
557 /* Don't use the FILE_OVERWRITE{_IF} flags here. See below for an
558 explanation, why that's not such a good idea. */
559 if ((flags & O_EXCL) && (flags & O_CREAT))
560 create_disposition = FILE_CREATE;
562 create_disposition = (flags & O_CREAT) ? FILE_OPEN_IF : FILE_OPEN;
564 if (get_device () == FH_FS)
566 /* Add the reparse point flag to native symlinks, otherwise we open the
567 target, not the symlink. This would break lstat. */
568 if (pc.is_rep_symlink ())
569 options |= FILE_OPEN_REPARSE_POINT;
573 /* Make sure we can read EAs of files on an NFS share. Also make
574 sure that we're going to act on the file itself, even if it's a
576 access |= FILE_READ_EA;
579 if (query_open () >= query_write_control)
580 access |= FILE_WRITE_EA;
581 plen = sizeof nfs_aol_ffei;
582 p = (PFILE_FULL_EA_INFORMATION) &nfs_aol_ffei;
586 /* Starting with Windows 2000, when trying to overwrite an already
587 existing file with FILE_ATTRIBUTE_HIDDEN and/or FILE_ATTRIBUTE_SYSTEM
588 attribute set, CreateFile fails with ERROR_ACCESS_DENIED.
589 Per MSDN you have to create the file with the same attributes as
590 already specified for the file. */
591 if (((flags & O_CREAT) || create_disposition == FILE_OVERWRITE)
592 && has_attribute (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
593 file_attributes |= pc.file_attributes ();
597 file_attributes |= FILE_ATTRIBUTE_NORMAL;
601 /* When creating a file on an NFS share, we have to set the
602 file mode by writing a NFS fattr3 structure with the
603 correct mode bits set. */
604 access |= FILE_WRITE_EA;
605 plen = sizeof (FILE_FULL_EA_INFORMATION) + sizeof (NFS_V3_ATTR)
607 p = (PFILE_FULL_EA_INFORMATION) alloca (plen);
608 p->NextEntryOffset = 0;
610 p->EaNameLength = sizeof (NFS_V3_ATTR) - 1;
611 p->EaValueLength = sizeof (fattr3);
612 strcpy (p->EaName, NFS_V3_ATTR);
613 fattr3 *nfs_attr = (fattr3 *) (p->EaName
614 + p->EaNameLength + 1);
615 memset (nfs_attr, 0, sizeof (fattr3));
616 nfs_attr->type = NF3REG;
617 nfs_attr->mode = mode;
619 else if (!has_acls () && !(mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
620 /* If mode has no write bits set, and ACLs are not used, we set
621 the DOS R/O attribute. */
622 file_attributes |= FILE_ATTRIBUTE_READONLY;
623 /* The file attributes are needed for later use in, e.g. fchmod. */
624 pc.file_attributes (file_attributes);
625 /* Never set the WRITE_DAC flag here. Calls to fstat may return
626 wrong st_ctime information after calls to fchmod, fchown, etc
627 because Windows only guarantees the update of metadata when
628 the handle is closed or flushed. However, flushing the file
629 on every fstat to enforce POSIXy stat behaviour is excessivly
630 slow, compared to an extra open/close to change the file's
631 security descriptor. */
635 status = NtCreateFile (&fh, access, &attr, &io, NULL, file_attributes, shared,
636 create_disposition, options, p, plen);
637 if (!NT_SUCCESS (status))
639 /* Trying to create a directory should return EISDIR, not ENOENT. */
640 PUNICODE_STRING upath = pc.get_nt_native_path ();
641 if (status == STATUS_OBJECT_NAME_INVALID && (flags & O_CREAT)
642 && upath->Buffer[upath->Length / sizeof (WCHAR) - 1] == '\\')
645 __seterrno_from_nt_status (status);
650 /* Always create files using a NULL SD. Create correct permission bits
651 afterwards, maintaining the owner and group information just like chmod.
653 This is done for two reasons.
655 On Windows filesystems we need to create the file with default
656 permissions to allow inheriting ACEs. When providing an explicit DACL
657 in calls to [Nt]CreateFile, the created file will not inherit default
658 permissions from the parent object. This breaks not only Windows
659 inheritance, but also POSIX ACL inheritance.
661 Another reason to do this are remote shares. Files on a remote share
662 are created as the user used for authentication. In a domain that's
663 usually the user you're logged in as. Outside of a domain you're
664 authenticating using a local user account on the sharing machine.
665 If the SIDs of the client machine are used, that's entirely
666 unexpected behaviour. Doing it like we do here creates the expected SD
667 in a domain as well as on standalone servers.
668 This is the result of a discussion on the samba-technical list, starting at
669 http://lists.samba.org/archive/samba-technical/2008-July/060247.html */
670 if (io.Information == FILE_CREATED && has_acls ())
671 set_file_attribute (fh, pc, ILLEGAL_UID, ILLEGAL_GID, S_JUSTCREATED | mode);
673 /* If you O_TRUNC a file on Linux, the data is truncated, but the EAs are
674 preserved. If you open a file on Windows with FILE_OVERWRITE{_IF} or
675 FILE_SUPERSEDE, all streams are truncated, including the EAs. So we don't
676 use the FILE_OVERWRITE{_IF} flags, but instead just open the file and set
677 the size of the data stream explicitely to 0. Apart from being more Linux
678 compatible, this implementation has the pleasant side-effect to be more
679 than 5% faster than using FILE_OVERWRITE{_IF} (tested on W7 32 bit). */
680 if ((flags & O_TRUNC)
681 && (flags & O_ACCMODE) != O_RDONLY
682 && io.Information != FILE_CREATED
683 && get_device () == FH_FS)
685 FILE_END_OF_FILE_INFORMATION feofi = { EndOfFile:{ QuadPart:0 } };
686 status = NtSetInformationFile (fh, &io, &feofi, sizeof feofi,
687 FileEndOfFileInformation);
688 /* In theory, truncating the file should never fail, since the opened
689 handle has FILE_WRITE_DATA permissions, which is all you need to
690 be allowed to truncate a file. Better safe than sorry. */
691 if (!NT_SUCCESS (status))
693 __seterrno_from_nt_status (status);
700 set_flags (flags, pc.binmode ());
705 debug_printf ("%x = NtCreateFile "
706 "(%p, %x, %S, io, NULL, %x, %x, %x, %x, NULL, 0)",
707 status, fh, access, pc.get_nt_native_path (), file_attributes,
708 shared, create_disposition, options);
710 syscall_printf ("%d = fhandler_base::open(%S, %p)",
711 res, pc.get_nt_native_path (), flags);
716 open buffer in binary mode? Just do the read.
718 open buffer in text mode? Scan buffer for control zs and handle
719 the first one found. Then scan buffer, converting every \r\n into
720 an \n. If last char is an \r, look ahead one more char, if \n then
721 modify \r, if not, remember char.
724 fhandler_base::read (void *in_ptr, size_t& len)
726 char *ptr = (char *) in_ptr;
727 ssize_t copied_chars = get_readahead_into_buffer (ptr, len);
731 len = (size_t) copied_chars;
738 len = (size_t) copied_chars;
742 raw_read (ptr + copied_chars, len);
745 else if ((ssize_t) len > 0)
750 if (rbinary () || (ssize_t) len <= 0)
753 /* Scan buffer and turn \r\n into \n */
754 char *src, *dst, *end;
759 /* Read up to the last but one char - the last char needs special handling */
762 if (*src == '\r' && src[1] == '\n')
767 /* If not beyond end and last char is a '\r' then read one more
768 to see if we should translate this one too */
771 else if (*src != '\r')
777 raw_read (&c1, c1len);
784 set_readahead_valid (1, c1);
789 len = dst - (char *) ptr;
792 if (strace.active ())
794 char buf[16 * 6 + 1];
797 for (int i = 0; i < copied_chars && i < 16; ++i)
799 unsigned char c = ((unsigned char *) ptr)[i];
800 __small_sprintf (p, " %c", c);
804 debug_printf ("read %d bytes (%s%s)", copied_chars, buf,
805 copied_chars > 16 ? " ..." : "");
810 debug_printf ("returning %d, %s mode", len, rbinary () ? "binary" : "text");
814 fhandler_base::write (const void *ptr, size_t len)
818 FILE_POSITION_INFORMATION fpi;
819 FILE_STANDARD_INFORMATION fsi;
823 did_lseek (false); /* don't do it again */
825 if (!(get_flags () & O_APPEND)
826 && NT_SUCCESS (NtQueryInformationFile (get_output_handle (),
827 &io, &fsi, sizeof fsi,
828 FileStandardInformation))
829 && NT_SUCCESS (NtQueryInformationFile (get_output_handle (),
830 &io, &fpi, sizeof fpi,
831 FilePositionInformation))
832 && fpi.CurrentByteOffset.QuadPart
833 >= fsi.EndOfFile.QuadPart + (128 * 1024)
834 && (pc.fs_flags () & FILE_SUPPORTS_SPARSE_FILES))
836 /* If the file system supports sparse files and the application
837 is writing after a long seek beyond EOF, convert the file to
840 status = NtFsControlFile (get_output_handle (), NULL, NULL, NULL,
841 &io, FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
842 syscall_printf ("%p = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
843 status, pc.get_nt_native_path ());
849 debug_printf ("binary write");
850 res = raw_write (ptr, len);
854 debug_printf ("text write");
855 /* This is the Microsoft/DJGPP way. Still not ideal, but it's
857 Modified slightly by CGF 2000-10-07 */
859 int left_in_data = len;
860 char *data = (char *)ptr;
863 while (left_in_data > 0)
865 char buf[CHUNK_SIZE + 1], *buf_ptr = buf;
866 int left_in_buf = CHUNK_SIZE;
868 while (left_in_buf > 0 && left_in_data > 0)
879 if (left_in_data > 0 && ch == '\r' && *data == '\n')
881 *buf_ptr++ = *data++;
887 /* We've got a buffer-full, or we're out of data. Write it out */
889 int want = buf_ptr - buf;
890 if ((nbytes = raw_write (buf, want)) == want)
892 /* Keep track of how much written not counting additional \r's */
893 res = data - (char *)ptr;
898 res = -1; /* Error */
900 res += nbytes; /* Partial write. Return total bytes written. */
901 break; /* All done */
909 fhandler_base::readv (const struct iovec *const iov, const int iovcnt,
913 assert (iovcnt >= 1);
919 read (iov->iov_base, len);
923 if (tot == -1) // i.e. if not pre-calculated by the caller.
926 const struct iovec *iovptr = iov + iovcnt;
930 len += iovptr->iov_len;
932 while (iovptr != iov);
938 char *buf = (char *) malloc (len);
947 ssize_t nbytes = (ssize_t) len;
949 const struct iovec *iovptr = iov;
954 const int frag = min (nbytes, (ssize_t) iovptr->iov_len);
955 memcpy (iovptr->iov_base, p, frag);
966 fhandler_base::writev (const struct iovec *const iov, const int iovcnt,
970 assert (iovcnt >= 1);
973 return write (iov->iov_base, iov->iov_len);
975 if (tot == -1) // i.e. if not pre-calculated by the caller.
978 const struct iovec *iovptr = iov + iovcnt;
982 tot += iovptr->iov_len;
984 while (iovptr != iov);
992 char *const buf = (char *) malloc (tot);
1001 const struct iovec *iovptr = iov;
1006 const int frag = min (nbytes, (ssize_t) iovptr->iov_len);
1007 memcpy (bufptr, iovptr->iov_base, frag);
1012 ssize_t ret = write (buf, tot);
1018 fhandler_base::lseek (_off64_t offset, int whence)
1022 FILE_POSITION_INFORMATION fpi;
1023 FILE_STANDARD_INFORMATION fsi;
1025 /* Seeks on text files is tough, we rewind and read till we get to the
1028 if (whence != SEEK_CUR || offset != 0)
1030 if (whence == SEEK_CUR)
1031 offset -= ralen - raixget;
1032 set_readahead_valid (0);
1038 fpi.CurrentByteOffset.QuadPart = offset;
1041 status = NtQueryInformationFile (get_handle (), &io, &fpi, sizeof fpi,
1042 FilePositionInformation);
1043 if (!NT_SUCCESS (status))
1045 __seterrno_from_nt_status (status);
1048 fpi.CurrentByteOffset.QuadPart += offset;
1050 default: /* SEEK_END */
1051 status = NtQueryInformationFile (get_handle (), &io, &fsi, sizeof fsi,
1052 FileStandardInformation);
1053 if (!NT_SUCCESS (status))
1055 __seterrno_from_nt_status (status);
1058 fpi.CurrentByteOffset.QuadPart = fsi.EndOfFile.QuadPart + offset;
1062 debug_printf ("setting file pointer to %U", fpi.CurrentByteOffset.QuadPart);
1063 status = NtSetInformationFile (get_handle (), &io, &fpi, sizeof fpi,
1064 FilePositionInformation);
1065 if (!NT_SUCCESS (status))
1067 __seterrno_from_nt_status (status);
1070 _off64_t res = fpi.CurrentByteOffset.QuadPart;
1072 /* When next we write(), we will check to see if *this* seek went beyond
1073 the end of the file and if so, potentially sparsify the file. */
1076 /* If this was a SEEK_CUR with offset 0, we still might have
1077 readahead that we have to take into account when calculating
1078 the actual position for the application. */
1079 if (whence == SEEK_CUR)
1080 res -= ralen - raixget;
1086 fhandler_base::pread (void *, size_t, _off64_t)
1093 fhandler_base::pwrite (void *, size_t, _off64_t)
1100 fhandler_base::close_with_arch ()
1107 debug_printf ("closing passed in archetype, usecount %d", usecount);
1110 debug_printf ("not closing passed in archetype, usecount %d", usecount);
1115 else if (!archetype)
1120 if (archetype_usecount (-1) == 0)
1122 debug_printf ("closing archetype");
1127 debug_printf ("not closing archetype");
1135 cygheap->fdtab.delete_archetype (archetype);
1142 fhandler_base::close ()
1146 syscall_printf ("closing '%s' handle %p", get_name (), get_handle ());
1147 if (nohandle () || CloseHandle (get_handle ()))
1151 paranoid_printf ("CloseHandle failed, %E");
1159 flush_async_io (void *arg)
1161 fhandler_base_overlapped *fh = (fhandler_base_overlapped *) arg;
1162 debug_only_printf ("waiting for %s I/O for %s",
1163 (fh->get_access () & GENERIC_WRITE) ? "write" : "read",
1165 SetEvent (fh->get_overlapped ()->hEvent); /* force has_ongoing_io to block */
1166 bool res = fh->has_ongoing_io ();
1167 debug_printf ("finished waiting for I/O from %s, res %d", fh->get_name (),
1172 InterlockedDecrement (&fhandler_base_overlapped::asio_close_counter);
1173 SetEvent (fhandler_base_overlapped::asio_done);
1175 _my_tls._ctinfo->auto_release ();
1180 fhandler_base_overlapped::flush_all_async_io ()
1182 while (asio_close_counter > 0)
1183 if (WaitForSingleObject (asio_done, INFINITE) != WAIT_OBJECT_0)
1185 system_printf ("WaitForSingleObject failed, possible data loss in pipe, %E");
1188 asio_close_counter = 0;
1190 CloseHandle (asio_done);
1193 /* Start a thread to handle closing of overlapped asynchronous I/O since
1194 Windows amazingly does not seem to always flush I/O on close. */
1196 fhandler_base_overlapped::check_later ()
1198 set_close_on_exec (true);
1201 && !(asio_done = CreateEvent (&sec_none_nih, false, false,
1202 shared_name (buf, "asio",
1203 GetCurrentProcessId ()))))
1204 api_fatal ("CreateEvent failed, %E");
1206 InterlockedIncrement (&asio_close_counter);
1207 if (!new cygthread(flush_async_io, this, "flasio"))
1208 api_fatal ("couldn't create a thread to track async I/O, %E");
1209 debug_printf ("started thread to handle asynchronous closing for %s", get_name ());
1213 fhandler_base_overlapped::close ()
1216 /* Need to treat non-blocking I/O specially because Windows appears to
1218 if (is_nonblocking () && has_ongoing_io ())
1220 clone (HEAP_3_FHANDLER)->check_later ();
1225 destroy_overlapped ();
1226 res = fhandler_base::close ();
1232 fhandler_base::ioctl (unsigned int cmd, void *buf)
1239 set_nonblocking (*(int *) buf);
1253 syscall_printf ("%d = ioctl(%x, %p)", res, cmd, buf);
1258 fhandler_base::lock (int, struct __flock64 *)
1265 fhandler_base::fstat (struct __stat64 *buf)
1267 if (is_fs_special ())
1268 return fstat_fs (buf);
1270 switch (get_device ())
1273 buf->st_mode = S_IFIFO | S_IRUSR | S_IWUSR;
1276 buf->st_mode = S_IFIFO | S_IWUSR;
1279 buf->st_mode = S_IFIFO | S_IRUSR;
1282 buf->st_mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH;
1285 buf->st_mode = S_IFCHR | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH;
1289 buf->st_uid = geteuid32 ();
1290 buf->st_gid = getegid32 ();
1292 buf->st_blksize = PREFERRED_IO_BLKSIZE;
1294 buf->st_ctim.tv_sec = 1164931200L; /* Arbitrary value: 2006-12-01 */
1295 buf->st_ctim.tv_nsec = 0L;
1296 buf->st_birthtim = buf->st_ctim;
1297 buf->st_mtim.tv_sec = time (NULL); /* Arbitrary value: current time,
1299 buf->st_mtim.tv_nsec = 0L;
1300 buf->st_atim = buf->st_mtim;
1306 fhandler_base::fstatvfs (struct statvfs *sfs)
1308 /* If we hit this base implementation, it's some device in /dev.
1309 Just call statvfs on /dev for simplicity. */
1310 path_conv pc ("/dev", PC_KEEP_HANDLE);
1311 fhandler_disk_file fh (pc);
1312 return fh.fstatvfs (sfs);
1316 fhandler_base::init (HANDLE f, DWORD a, mode_t bin)
1320 a &= GENERIC_READ | GENERIC_WRITE;
1322 if (a == GENERIC_READ)
1324 else if (a == GENERIC_WRITE)
1326 else if (a == (GENERIC_READ | GENERIC_WRITE))
1328 set_flags (flags | bin);
1330 debug_printf ("created new fhandler_base for handle %p, bin %d", f, rbinary ());
1335 fhandler_base::dup (fhandler_base *child, int)
1337 debug_printf ("in fhandler_base dup");
1340 if (!nohandle () && !archetype)
1342 if (!DuplicateHandle (GetCurrentProcess (), get_handle (),
1343 GetCurrentProcess (), &nh,
1344 0, TRUE, DUPLICATE_SAME_ACCESS))
1346 debug_printf ("dup(%s) failed, handle %x, %E",
1347 get_name (), get_handle ());
1353 child->set_io_handle (nh);
1359 fhandler_base_overlapped::dup (fhandler_base *child, int flags)
1361 int res = fhandler_base::dup (child, flags) ||
1362 ((fhandler_base_overlapped *) child)->setup_overlapped ();
1366 int fhandler_base::fcntl (int cmd, void *arg)
1373 res = close_on_exec () ? FD_CLOEXEC : 0;
1376 set_close_on_exec (((int) arg & FD_CLOEXEC) ? 1 : 0);
1381 debug_printf ("GETFL: %p", res);
1385 /* Only O_APPEND, O_ASYNC and O_NONBLOCK/O_NDELAY are allowed.
1386 Each other flag will be ignored.
1387 Since O_ASYNC isn't defined in fcntl.h it's currently
1389 const int allowed_flags = O_APPEND | O_NONBLOCK_MASK;
1390 int new_flags = (int) arg & allowed_flags;
1391 /* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag.
1392 Set only the flag that has been passed in. If both are set, just
1393 record O_NONBLOCK. */
1394 if ((new_flags & OLD_O_NDELAY) && (new_flags & O_NONBLOCK))
1395 new_flags &= ~OLD_O_NDELAY;
1396 set_flags ((get_flags () & ~allowed_flags) | new_flags);
1408 /* Base terminal handlers. These just return errors. */
1411 fhandler_base::tcflush (int)
1418 fhandler_base::tcsendbreak (int)
1425 fhandler_base::tcdrain ()
1432 fhandler_base::tcflow (int)
1439 fhandler_base::tcsetattr (int, const struct termios *)
1446 fhandler_base::tcgetattr (struct termios *)
1453 fhandler_base::tcsetpgrp (const pid_t)
1460 fhandler_base::tcgetpgrp ()
1467 fhandler_base::tcgetsid ()
1474 fhandler_base::ptsname_r (char *, size_t)
1480 /* Normal I/O constructor */
1481 fhandler_base::fhandler_base () :
1501 /* Normal I/O destructor */
1502 fhandler_base::~fhandler_base ()
1508 /**********************************************************************/
1511 fhandler_dev_null::fhandler_dev_null () :
1517 fhandler_base::set_no_inheritance (HANDLE &h, bool not_inheriting)
1519 if (!SetHandleInformation (h, HANDLE_FLAG_INHERIT,
1520 not_inheriting ? 0 : HANDLE_FLAG_INHERIT))
1521 debug_printf ("SetHandleInformation failed, %E");
1522 #ifdef DEBUGGING_AND_FDS_PROTECTED
1524 setclexec (oh, h, not_inheriting);
1529 fhandler_base::fork_fixup (HANDLE parent, HANDLE &h, const char *name)
1533 if (/* !is_socket () && */ !close_on_exec ())
1534 debug_printf ("handle %p already opened", h);
1535 else if (!DuplicateHandle (parent, h, GetCurrentProcess (), &h,
1536 0, !close_on_exec (), DUPLICATE_SAME_ACCESS))
1537 system_printf ("%s - %E, handle %s<%p>", get_name (), name, h);
1548 fhandler_base::set_close_on_exec (bool val)
1551 set_no_inheritance (io_handle, val);
1552 close_on_exec (val);
1553 debug_printf ("set close_on_exec for %s to %d", get_name (), val);
1557 fhandler_base::fixup_after_fork (HANDLE parent)
1559 debug_printf ("inheriting '%s' from parent", get_name ());
1561 fork_fixup (parent, io_handle, "io_handle");
1562 /* POSIX locks are not inherited across fork. */
1564 del_my_locks (after_fork);
1568 fhandler_base_overlapped::fixup_after_fork (HANDLE parent)
1570 setup_overlapped ();
1571 fhandler_base::fixup_after_fork (parent);
1575 fhandler_base::fixup_after_exec ()
1577 debug_printf ("here for '%s'", get_name ());
1578 if (unique_id && close_on_exec ())
1579 del_my_locks (after_exec);
1582 fhandler_base_overlapped::fixup_after_exec ()
1584 setup_overlapped ();
1585 fhandler_base::fixup_after_exec ();
1589 fhandler_base::is_nonblocking ()
1591 return (openflags & O_NONBLOCK_MASK) != 0;
1595 fhandler_base::set_nonblocking (int yes)
1597 int current = openflags & O_NONBLOCK_MASK;
1598 int new_flags = yes ? (!current ? O_NONBLOCK : current) : 0;
1599 openflags = (openflags & ~O_NONBLOCK_MASK) | new_flags;
1603 fhandler_base::mkdir (mode_t)
1613 fhandler_base::rmdir ()
1617 else if (!pc.isdir ())
1618 set_errno (ENOTDIR);
1625 fhandler_base::opendir (int fd)
1627 set_errno (ENOTDIR);
1632 fhandler_base::readdir (DIR *, dirent *)
1638 fhandler_base::telldir (DIR *)
1640 set_errno (ENOTDIR);
1645 fhandler_base::seekdir (DIR *, long)
1647 set_errno (ENOTDIR);
1651 fhandler_base::rewinddir (DIR *)
1653 set_errno (ENOTDIR);
1657 fhandler_base::closedir (DIR *)
1659 set_errno (ENOTDIR);
1664 fhandler_base::fchmod (mode_t mode)
1666 extern int chmod_device (path_conv& pc, mode_t mode);
1667 if (pc.is_fs_special ())
1668 return chmod_device (pc, mode);
1669 /* By default, just succeeds. */
1674 fhandler_base::fchown (__uid32_t uid, __gid32_t gid)
1676 if (pc.is_fs_special ())
1677 return ((fhandler_disk_file *) this)->fhandler_disk_file::fchown (uid, gid);
1678 /* By default, just succeeds. */
1683 fhandler_base::facl (int cmd, int nentries, __aclent32_t *aclbufp)
1689 /* By default, just succeeds. */
1695 else if (nentries < MIN_ACL_ENTRIES)
1699 aclbufp[0].a_type = USER_OBJ;
1700 aclbufp[0].a_id = myself->uid;
1701 aclbufp[0].a_perm = (S_IRUSR | S_IWUSR) >> 6;
1702 aclbufp[1].a_type = GROUP_OBJ;
1703 aclbufp[1].a_id = myself->gid;
1704 aclbufp[1].a_perm = (S_IRGRP | S_IWGRP) >> 3;
1705 aclbufp[2].a_type = OTHER_OBJ;
1706 aclbufp[2].a_id = ILLEGAL_GID;
1707 aclbufp[2].a_perm = S_IROTH | S_IWOTH;
1708 aclbufp[3].a_type = CLASS_OBJ;
1709 aclbufp[3].a_id = ILLEGAL_GID;
1710 aclbufp[3].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
1711 res = MIN_ACL_ENTRIES;
1715 res = MIN_ACL_ENTRIES;
1725 fhandler_base::fgetxattr (const char *name, void *value, size_t size)
1727 set_errno (ENOTSUP);
1732 fhandler_base::fsetxattr (const char *name, const void *value, size_t size,
1735 set_errno (ENOTSUP);
1740 fhandler_base::fadvise (_off64_t offset, _off64_t length, int advice)
1747 fhandler_base::ftruncate (_off64_t length, bool allow_truncate)
1754 fhandler_base::link (const char *newpath)
1761 fhandler_base::utimens (const struct timespec *tvp)
1763 if (is_fs_special ())
1764 return utimens_fs (tvp);
1771 fhandler_base::fsync ()
1773 if (!get_handle () || nohandle ())
1778 if (pc.isdir ()) /* Just succeed. */
1780 if (FlushFileBuffers (get_handle ()))
1783 /* Ignore ERROR_INVALID_FUNCTION because FlushFileBuffers() always fails
1784 with this code on raw devices which are unbuffered by default. */
1785 DWORD errcode = GetLastError();
1786 if (errcode == ERROR_INVALID_FUNCTION)
1789 __seterrno_from_win_error (errcode);
1794 fhandler_base::fpathconf (int v)
1801 return pc.fs_is_ntfs () || pc.fs_is_samba () || pc.fs_is_nfs ()
1814 /* NAME_MAX is without trailing \0 */
1817 ret = NT_MAX_PATH - strlen (get_name ()) - 2;
1818 return ret < 0 ? 0 : ret > NAME_MAX ? NAME_MAX : ret;
1820 /* PATH_MAX is with trailing \0 */
1823 ret = NT_MAX_PATH - strlen (get_name ()) - 1;
1824 return ret < 0 ? 0 : ret > PATH_MAX ? PATH_MAX : ret;
1827 || get_device () == FH_FIFO || get_device () == FH_PIPE
1828 || get_device () == FH_PIPER || get_device () == FH_PIPEW)
1832 case _PC_CHOWN_RESTRICTED:
1838 return _POSIX_VDISABLE;
1846 case _PC_FILESIZEBITS:
1847 return FILESIZEBITS;
1848 case _PC_2_SYMLINKS:
1850 case _PC_SYMLINK_MAX:
1852 case _PC_POSIX_PERMISSIONS:
1853 case _PC_POSIX_SECURITY:
1854 if (get_device () == FH_FS)
1855 return pc.has_acls () || pc.fs_is_nfs ();
1865 /* Overlapped I/O */
1867 int __stdcall __attribute__ ((regparm (1)))
1868 fhandler_base_overlapped::setup_overlapped ()
1870 OVERLAPPED *ov = get_overlapped_buffer ();
1871 memset (ov, 0, sizeof (*ov));
1872 set_overlapped (ov);
1873 ov->hEvent = CreateEvent (&sec_none_nih, true, true, NULL);
1875 return ov->hEvent ? 0 : -1;
1878 void __stdcall __attribute__ ((regparm (1)))
1879 fhandler_base_overlapped::destroy_overlapped ()
1881 OVERLAPPED *ov = get_overlapped ();
1882 if (ov && ov->hEvent)
1884 CloseHandle (ov->hEvent);
1888 get_overlapped () = NULL;
1891 bool __stdcall __attribute__ ((regparm (1)))
1892 fhandler_base_overlapped::has_ongoing_io ()
1897 if (!IsEventSignalled (get_overlapped ()->hEvent))
1901 GetOverlappedResult (get_output_handle (), get_overlapped (), &nbytes, true);
1905 fhandler_base_overlapped::wait_return __stdcall __attribute__ ((regparm (3)))
1906 fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *bytes, bool nonblocking, DWORD len)
1908 if (!get_overlapped ())
1909 return inres ? overlapped_success : overlapped_error;
1911 wait_return res = overlapped_unknown;
1915 else if ((err = GetLastError ()) != ERROR_IO_PENDING)
1916 res = overlapped_error;
1917 else if (!nonblocking)
1920 SetEvent (get_overlapped ()->hEvent); /* Force immediate WFMO return */
1923 *bytes = len; /* Assume that this worked */
1924 io_pending = true; /* but don't allow subsequent */
1925 res = overlapped_success; /* writes until completed */
1927 if (res == overlapped_unknown)
1929 DWORD wfres = cygwait (get_overlapped ()->hEvent);
1930 HANDLE h = writing ? get_output_handle () : get_handle ();
1933 wores = 0; /* closed in another thread or via signal handler */
1936 /* Cancelling here to prevent races. It's possible that the I/O has
1937 completed already, in which case this is a no-op. Otherwise,
1938 WFMO returned because 1) This is a non-blocking call, 2) a signal
1939 arrived, or 3) the operation was cancelled. These cases may be
1940 overridden by the return of GetOverlappedResult which could detect
1941 that I/O completion occurred. */
1943 wores = GetOverlappedResult (h, get_overlapped (), bytes, false);
1944 err = GetLastError ();
1945 ResetEvent (get_overlapped ()->hEvent); /* Probably not needed but CYA */
1946 debug_printf ("wfres %d, wores %d, bytes %u", wfres, wores, *bytes);
1949 res = overlapped_success; /* operation succeeded */
1950 else if (wfres == WAIT_OBJECT_0 + 1)
1952 err = ERROR_INVALID_AT_INTERRUPT_TIME; /* forces an EINTR below */
1953 debug_printf ("signal");
1954 res = overlapped_error;
1956 else if (nonblocking)
1957 res = overlapped_nonblocking_no_data; /* more handling below */
1958 else if (wfres == WAIT_OBJECT_0 + 2)
1959 pthread::static_cancel_self (); /* never returns */
1962 debug_printf ("GetOverLappedResult failed, h %p, bytes %u, %E", h, *bytes);
1963 res = overlapped_error;
1967 if (res == overlapped_success)
1968 debug_printf ("normal %s, %u bytes", writing ? "write" : "read", *bytes);
1969 else if (res == overlapped_nonblocking_no_data)
1971 *bytes = (DWORD) -1;
1973 debug_printf ("no data to read for nonblocking I/O");
1975 else if (err == ERROR_HANDLE_EOF || err == ERROR_BROKEN_PIPE)
1977 debug_printf ("EOF, %E");
1979 res = overlapped_success;
1980 if (writing && err == ERROR_BROKEN_PIPE)
1985 debug_printf ("res %u, Win32 Error %u", (unsigned) res, err);
1986 *bytes = (DWORD) -1;
1987 __seterrno_from_win_error (err);
1988 if (writing && err == ERROR_NO_DATA)
1995 void __stdcall __attribute__ ((regparm (3)))
1996 fhandler_base_overlapped::raw_read (void *ptr, size_t& len)
2002 bool res = ReadFile (get_handle (), ptr, len, &nbytes,
2004 switch (wait_overlapped (res, false, &nbytes, is_nonblocking ()))
2006 default: /* Added to quiet gcc */
2007 case overlapped_success:
2008 case overlapped_error:
2009 keep_looping = false;
2013 while (keep_looping);
2014 len = (size_t) nbytes;
2017 ssize_t __stdcall __attribute__ ((regparm (3)))
2018 fhandler_base_overlapped::raw_write (const void *ptr, size_t len)
2021 if (has_ongoing_io ())
2024 nbytes = (DWORD) -1;
2029 if (!max_atomic_write || len < max_atomic_write)
2031 else if (is_nonblocking ())
2032 chunk = len = max_atomic_write;
2034 chunk = max_atomic_write;
2037 DWORD nbytes_now = 0;
2038 /* Write to fd in smaller chunks, accumlating a total.
2039 If there's an error, just return the accumulated total
2040 unless the first write fails, in which case return value
2041 from wait_overlapped(). */
2042 while (nbytes < len)
2044 size_t left = len - nbytes;
2050 bool res = WriteFile (get_output_handle (), ptr, len1, &nbytes_now,
2052 switch (wait_overlapped (res, true, &nbytes_now,
2053 is_nonblocking (), len1))
2055 case overlapped_success:
2056 ptr = ((char *) ptr) + chunk;
2057 nbytes += nbytes_now;
2058 /* fall through intentionally */
2059 case overlapped_error:
2060 len = 0; /* terminate loop */
2061 case overlapped_unknown:
2062 case overlapped_nonblocking_no_data:
2067 nbytes = nbytes_now;